【bzoj1143: [CTSC2008]祭祀river】有向无环图的最长反链
来源:互联网 发布:重装系统安装不了软件 编辑:程序博客网 时间:2024/04/29 06:06
1143: [CTSC2008]祭祀river
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3192 Solved: 1632
[Submit][Status][Discuss]
Description
Input
Output
第一行包含一个整数K,表示最多能选取的祭祀点的个数。
Sample Input
1 2
3 4
3 2
4 2
Sample Output
【样例说明】
在样例给出的水系中,不存在一种方法能够选择三个或者三个以上的祭祀点。包含两个祭祀点的测试点的方案有两种:
选择岔口1与岔口3(如样例输出第二行),选择岔口1与岔口4。
水流可以从任意岔口流至岔口2。如果在岔口2建立祭祀点,那么任意其他岔口都不能建立祭祀点
但是在最优的一种祭祀点的选取方案中我们可以建立两个祭祀点,所以岔口2不能建立祭祀点。对于其他岔口
至少存在一个最优方案选择该岔口为祭祀点,所以输出为1011。
icpc上居然出了这个原题,就爆炸了,回来补一补二分图和有向无环图的东西。
1、二分图最大匹配
匈牙利算法O(V*E)的复杂度内可求出二分图的最大匹配
2、二分图最小点覆盖
找到点数最少的一个点集,使得二分图里的所有边至少有一个端点是在该点集中
最小点覆盖=最大匹配
3、二分图最小边覆盖
找到边数最少的一个边集,使得二分图里的所有点至少是一条边的端点
最小边覆盖=图中点的个数-最大匹配
证明:把最大匹配的边都加入,则剩下的点之间都没有边,那么再把剩下的点都连接起来,边数=最大匹配+图中点的个数-2*最大匹配=图中点的个数-最大匹配
4、二分图最大独立集
找到一个点数最大的点集,使得点集里的所有点对之间在原图里没有边。
最大独立集=图中点的个数-最大匹配
证明:把所有点加入点集中,最大独立集问题就转化为删去最少的点使得最终的点集是个独立集,那么 最大独立集=图中点的个数-最小点覆盖=图中点的个数-最大匹配
最小不相交路径覆盖:每一条路径经过的顶点各不相同。如,最小路径覆盖数为3:1->3>4,2,5。
最小可相交路径覆盖:每一条路径经过的顶点可以相同。如,最小路径覆盖数为2,1->3->4,2->3>5。
5、有向无环图最小不相交路径覆盖
用最少的不相交路径覆盖所有顶点。
将有向无环图中的各点拆点,i点拆为ai,bi ,对于一条边:i->j,转化为 ai->bj, 便可把有向无环图转化为二分图。有向无环图最小不相交路径覆盖=图中点的个数-最大匹配
证明:刚开始每个点为一条路径,则开始时有n条路径,对于二分图中的每一条匹配边就代表把两条路径变为一条路径,则最后的答案就是图中点的个数-最大匹配
6、有向无环图最小可相交路径覆盖
用最少的可相交路径覆盖所有顶点。
处理出有向无环图中所有点的到达情况,拆点,若i点可经过一条路径到达j点,那么连一条ai->bj 的边,此时有向图边转化为二分图,问题也就转化为5、有向无环图最小不相交路径覆盖。
在有向无环图中,有如下的一些定义和性质:
链:一条链是一些点的集合,链上任意两个点x, y,满足要么x 能到达y ,要么y 能到达x 。
反链:一条反链是一些点的集合,链上任意两个点x, y,满足x 不能到达y,且 y 也不能到达 x。
一个定理:最长反链长度 =最小链覆盖(用最少的链覆盖所有顶点)
对偶定理:最长链长度 =最小反链覆盖 ///????这个是什么意思没看懂,有人看懂了评论下
最小链覆盖也就是最小可相交路径覆盖。
经过上面一些乱七八糟的介绍,可以知道,这道题目就是求最长反链长度,就是求最长反链长度,就是求有向无环图最小可相交路径覆盖,见(6)
求各点的联通性可以用Floyd 也可以直接搜。
#include<cstdio>#include<cstring>#define M 1005#define N 105using namespace std;int k,K,fir[N],Fir[N],n,m,l,r,sign[N],link[N],vis[N];struct he{ int r,nx;}A[N*N],a[M];void add(int l,int r){ k++;a[k].r=r;a[k].nx=fir[l];fir[l]=k;}void Add(int l,int r){ K++;A[K].r=r;A[K].nx=Fir[l];Fir[l]=K;}void dfs(int x,int f){ vis[x]=1; if(x!=f)Add(f,x); for(int i=fir[x];i!=-1;i=a[i].nx) if(!vis[a[i].r]){ dfs(a[i].r,f); }}bool check(int x){ for(int i=Fir[x];i!=-1;i=A[i].nx) if(!sign[A[i].r]){ sign[A[i].r]=1; if(link[A[i].r]==0){ link[A[i].r]=x; return true; } if(check(link[A[i].r])){ link[A[i].r]=x; return true; } } return false;}int hungery(){ int ans=n; for(int i=1;i<=n;i++){ memset(sign,0,sizeof(sign)); if(check(i)) ans--; } return ans;}int main(){ memset(fir,-1,sizeof(fir)); memset(Fir,-1,sizeof(Fir)); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d%d",&l,&r); add(l,r); } for(int i=1;i<=n;i++){ memset(vis,0,sizeof(vis)); dfs(i,i); } printf("%d",hungery());}
- 【bzoj1143: [CTSC2008]祭祀river】有向无环图的最长反链
- 【BZOJ1143】[CTSC2008]祭祀river【最长反链】【传递闭包】
- BZOJ1143(CTSC2008)[祭祀river]--传递闭包+二分图最大匹配(求最长反链)
- 【CTSC2008】【BZOJ1143】祭祀river
- bzoj1143[CTSC2008]祭祀river
- BZOJ1143: [CTSC2008]祭祀river
- 【bzoj1143】【CTSC2008】【祭祀】【river】
- [bzoj1143][CTSC2008]祭祀river
- BZOJ1143: [CTSC2008]祭祀river
- 【bzoj1143】[CTSC2008]祭祀river
- bzoj1143[CTSC2008] 祭祀river
- bzoj1143: [CTSC2008]祭祀river
- bzoj1143 [CTSC2008]祭祀river
- [BZOJ1143]CTSC2008祭祀|最长反链|floyd|二分图匹配
- 最长反链(bzoj 1143: [CTSC2008]祭祀river)
- bzoj1143——CTSC2008祭祀river
- 【bzoj1143】 CTSC2008祭祀river 二分图匹配
- [BZOJ1143][CTSC2008]祭祀river 做题笔记
- unity3d 第一天
- 题目:利用条件运算符的嵌套来完成此题:学习成绩> =90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示。(java)
- 实验三Android手机拨号器开发
- 第十三周——项目三“是否二叉排序树”
- python解决SNIMissingWarning和InsecurePlatformWarning警告
- 【bzoj1143: [CTSC2008]祭祀river】有向无环图的最长反链
- JavaScript——ForEach语句和For…In语句的区别
- 【教程】html+css零基础入门教程之后代选择器(二十九)
- 程序员在阿里巴巴总部工作是怎么样的?
- 随机过程——学习资料(更新..........)
- 情缘渝韵
- 12.3学校作业
- Duilib 使用Zip资源
- Shell基础教程