题目链接

题目是求最长反链,反链指点集内任意两点不能互相到达。
根据Dilworth定理,在DAG中,\[最长反链 = 最小路径覆盖 = V - 最大匹配数\]
用Floyd求一遍传递闭包后,在所有可互相到达的点间连边。求二分图最大匹配。

也可以这么理解: 每一条边表示这两个点不能同时被选中,选出最少的一定不选的点(最小割?),用总点数减去就是答案了。

//1228kb    80ms
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
const int N=203,M=25000;int n,m,src,des,Enum,cur[N],H[N],nxt[M],fr[M],to[M],cap[M],lev[N],num[N],que[N],pre[N];
bool mp[103][103];inline int read()
{int now=0;register char c=gc();for(;!isdigit(c);c=gc());for(;isdigit(c);now=now*10+c-'0',c=gc());return now;
}
inline void AddEdge(int u,int v,int w)
{to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, fr[Enum]=u, cap[Enum]=w;to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum, fr[Enum]=v, cap[Enum]=0;
}
void Floyd()
{for(int k=1; k<=n; ++k)for(int i=1; i<=n; ++i)for(int j=1; j<=n; ++j)mp[i][j]|=(mp[i][k]&&mp[k][j]);
}
bool BFS()
{for(int i=src; i<des; ++i) lev[i]=des+1;lev[des]=0, que[0]=des; int h=0,t=1;while(h<t){int x=que[h++];for(int i=H[x]; i; i=nxt[i])if(lev[to[i]]==des+1 && cap[i^1])lev[to[i]]=lev[x]+1, que[t++]=to[i];}return lev[src]<=des;
}
void Augment(){for(int i=des; i!=src; i=fr[pre[i]])--cap[pre[i]], ++cap[pre[i]^1];
}
int ISAP()
{if(!BFS()) return 0;for(int i=src; i<=des; ++i) ++num[lev[i]],cur[i]=H[i];int x=src,res=0;while(lev[src]<=des){if(x==des) x=src,++res,Augment();bool can=0;for(int i=cur[x]; i; i=nxt[i])if(lev[to[i]]==lev[x]-1 && cap[i]){can=1, cur[x]=i, pre[x=to[i]]=i;break;}if(!can){int mn=des;for(int i=H[x]; i; i=nxt[i])if(cap[i]) mn=std::min(mn,lev[to[i]]);if(!--num[lev[x]]) break;++num[lev[x]=mn+1], cur[x]=H[x];if(x!=src) x=fr[pre[x]];}}return res;
}int main()
{n=read(),m=read(),Enum=1,src=0,des=n<<1|1;for(int u,v,i=1; i<=m; ++i) u=read(),v=read(),mp[u][v]=1;Floyd();for(int i=1; i<=n; ++i)for(int j=1; j<=n; ++j)if(mp[i][j]) AddEdge(i,j+n,1);for(int i=1; i<=n; ++i) AddEdge(src,i,1),AddEdge(i+n,des,1);printf("%d",n-ISAP());return 0;
}

转载于:https://www.cnblogs.com/SovietPower/p/8715695.html

BZOJ.1143.[CTSC2008]祭祀(Dilworth定理 最大流ISAP)相关推荐

  1. 最长反链(bzoj 1143: [CTSC2008]祭祀river)

    题目描述: 给你一个n个点m条边的有向无环图,求出最大点集满足其中任意两点间都不能存在路径 也就是对于所有的x, y∈S,x不能到达y,y也不能到达x 对于有向无环图(DAG): 链:一些点的集合,链 ...

  2. bzoj 1143: [CTSC2008]祭祀river

    Description 在遥远的东方,有一个神秘的民族,自称Y族.他们世代居住在水面上,奉龙王为神.每逢重大庆典, Y族都 会在水面上举办盛大的祭祀活动.我们可以把Y族居住地水系看成一个由岔口和河道组 ...

  3. 1143: [CTSC2008]祭祀river

    Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 4018  Solved: 2048 [Submit][Status][Discuss] Descri ...

  4. BZOJ1143[CTSC2008]祭祀river 偏序集及Dilworth定理

    这里讲一下我对偏序集的认识   如果有偏差可以评论我  我会修改 一:定义 (度娘上copy来的  不想看的可以跳过 设R是非空集合A上的一个二元关系,若R满足: 自反性.反对称性.传递性,则称R为A ...

  5. [bzoj1143][CTSC2008]祭祀river——DAG上最长反链,Dilworth定理,最大二分图匹配,Floyd

    题目大意: 给定一个DAG图,求最长反链(即一个点集,其中任意点两两不可以相互到达). 思路: 一开始我其实是想用求最大独立集的方法去求的.但是并不会(好像也过不去). 题目所要求的是最长反链,需要用 ...

  6. BZOJ.4160.[NEERC2009]Exclusive Access 2(状压DP Dilworth定理)

    BZOJ DAG中,根据\(Dilworth\)定理,有 \(最长反链=最小链覆盖\),也有 \(最长链=最小反链划分数-1\)(这个是指最短的最长链?并不是很确定=-=),即把所有点划分成最少的集合 ...

  7. BZOJ 1143 祭祀river 最长反链

    http://vfleaking.blog.163.com/blog/static/1748076342012918105514527/大前提:在有向无环图中链是一个点的集合,这个集合中任意两个元素v ...

  8. bzoj1143[CTSC2008]祭祀river

    bzoj1143[CTSC2008]祭祀river 题意: Y族居住地水系是一个由岔口和河道组成的网络.每条河道连接着两个岔口,并且水在河道内按照一个固定的方向流动.水系中不会有环流.由于人数众多的原 ...

  9. 【学习笔记】Dilworth 定理的构造性证明

    发现自己并不会 Dilworth 定理的构造性证明(原题要求输出方案),于是去 Wiki 上学习了一下.下文是我参照 Wiki 上的证明思路口胡的一个证明. 附例题:Codeforces 590E D ...

最新文章

  1. Google Mock(Gmock)简单使用和源码分析——源码分析
  2. Spring MVC 返回视图时添加的模型数据------POJO
  3. 一起学并发编程 - 钩子函数(shutdownHook)
  4. JS:1.3,函数(function)
  5. 一般试卷的纸张大小是多少_pdf试卷怎么打印在A3纸上
  6. npcap loopback adapter是什么意思_抖音限流是什么意思? 抖音为什么突然限流?
  7. 《掌门1对1微服务体系 Solar | 阿里巴巴 Sentinel 落地实践》
  8. 云计算演进历程与模式 - 初识云计算知识专栏(2)
  9. 英国四大运营商联合发文:驳斥“新冠病毒与5G有关”谣言
  10. Python常用图像处理
  11. java模拟内存溢出并分析_模拟内存溢出通过MAT分析
  12. jQery动态添加删除类样式
  13. Android 打开WIFI并快速获取WIFI的信息
  14. linux 配置java环境变量_linux配置java环境变量(详细)
  15. DSP28377 I2C开发笔记
  16. 数据库中候选码的求解
  17. 图像处理学习笔记(一)
  18. 用Excel制作贪吃蛇
  19. linux管理web项目目录结构图,WEB项目管理完整.doc
  20. 微信朋友圈爬虫python_python爬虫24 | 搞事情了,用 Appium 爬取你的微信朋友圈。...

热门文章

  1. 阻止 WSL 自动生成/etc/hosts 文件
  2. 【收藏】Maven 生成打包可执行jar包
  3. CentOS添加一个新的硬盘、添加分区到挂载的过程
  4. loadrunner脚本设计:集合点(批量放行实现真正的并发)
  5. Linux 下搭建 Scala 开发环境
  6. Python3 GUI编程入门程序示例
  7. Python3赋值运算符
  8. 中石油oj 2654: 序列合并
  9. python数据清洗实例_python 数据的清理行为实例详解
  10. java微妙_10个微妙的Java编码最佳实践