二分图相关问题
2016-04-06 20:27
323 查看
1。一个二分图中的最大匹配数等于这个图中的最小点覆盖数
König定理是一个二分图中很重要的定理,它的意思是,一个二分图中的最大匹配数等于这个图中的最小点覆盖数。最小点覆盖:假如选了一个点就相当于覆盖了以它为端点的所有边,你需要选择最少的点来覆盖所有的边。
2。最小路径覆盖=最小路径覆盖=|G|-最大匹配数
在一个N*N的有向图中,路径覆盖就是在图中找一些路经,使之覆盖了图中的所有顶点,
且任何一个顶点有且只有一条路径与之关联;(如果把这些路径中的每条路径从它的起始点走到它的终点,
那么恰好可以经过图中的每个顶点一次且仅一次);如果不考虑图中存在回路,那么每条路径就是一个弱连通子集.
由上面可以得出:
1.一个单独的顶点是一条路径;
2.如果存在一路径p1,p2,......pk,其中p1 为起点,pk为终点,那么在覆盖图中,顶点p1,p2,......pk不再与其它的
顶点之间存在有向边.
最小路径覆盖就是找出最小的路径条数,使之成为G的一个路径覆盖.
路径覆盖与二分图匹配的关系:最小路径覆盖=|G|-最大匹配数;
3。二分图最大独立集=顶点数-二分图最大匹配
独立集:图中任意两个顶点都不相连的顶点集合。
【bzoj1562】 变换序列
大概想了一下构图,果然还只是停留在09年noi的层面。。。
看了一下hzwer安利的题解,好多种解法,看了解法三和解法四(懒),发现字典序最小还是很实现的。
方法是:每次倒序找增广路,优先找序号小的点,这样就可以保证越前面的点越优,当然跟这道题的特殊构图方法也有一定联系。
一个很奇怪的地方是,题解的std明明跑了n遍的memset,怎么看都是n^2,时间只要80ms,不服。。。
可能我还有哪里没优化的地方,在这里MARK一下。
#include<cstdio> #include<algorithm> #define N 3010 using namespace std; int edgenum,ans,A,B,T1,T2,m; int match ,ban ,flag ,head ,mtime ,vet[9000010],next[9000010],map[3010][3010]; int a ,b ; void add(int u,int v){ edgenum++;vet[edgenum]=v;next[edgenum]=head[u];head[u]=edgenum; } int count(int x){ int re=0; while(x){ x-=x&(-x);//依次削去x最末尾的1 re++; }return re; } int dfs(int u){ int e=head[u]; if(ban[u]==T1)return 0; while(e>0){ int v=vet[e]; if(ban[v]!=T1&&flag[v]!=T2){ flag[v]=T2; if(mtime[v]!=T1||dfs(match[v])){ match[v]=u;mtime[v]=T1; return 1; } } e=next[e]; }return 0; } int inde(int x=0,int y=0){ int re=0;T1++; for(int i=1;i<=B;i++) if((map[x][i]==0)||(map[y][i]==0))ban[i]=T1,re++; for(int i=1;i<=B;i++) if(b[i]&1)//从奇数开始找 { T2++; if(dfs(i)==1)re++; }return re; } int main() { scanf("%d%d%d",&A,&B,&m);ans=1;int ja=0,oa=0; for(int i=1;i<=A;i++){ scanf("%d",&a[i]); if(a[i]%2==1)ja++;else oa++; }if(ja>0)if(oa>0)ans=2; for(int i=1;i<=B;i++)scanf("%d",&b[i]); for(int i=1;i<=m;i++){ int x,y;scanf("%d%d",&x,&y); map[x][y]=1;//反图中 map==1的ban掉 } for(int i=1;i<=B;i++)map[0][i]=1; for(int i=1;i<=B;i++)if(b[i]&1)//是奇数 for(int j=1;j<=B;j++)if((b[j]&1)==0)//是偶数 if(count(b[i]|b[j])%2==0)add(i,j); ans=max(ans,B-inde()); //寻找B图内最大独立集 for(int i=1;i<=A;i++) ans=max(ans,B-inde(i)+1); for(int i=1;i<=A;i++)if(a[i]%2==1) for(int j=1;j<=A;j++)if(a[j]%2==0){ ans=max(ans,B-inde(i,j)+2); } printf("%d\n",ans);return 0; }bzoj2744
相关文章推荐
- react native中使用react-native-viewpager实现的商品展示添加点击事件
- 初识ANSI C标准
- leetcode——58——Length of Last Word
- 学习javaEE每一天2016.4.6
- Spring MVC Junit4 单元測试 JunitTest
- spring junit class path resource [ /com/config/spring-core.xml] cannot be opened because it does not exist
- Java学习之垃圾回收
- 逻辑斯谛回归(代价函数,梯度下降) logistic regression--cost function and gradient descent
- 假日出行 什么样的移动电源才靠谱
- HTTP头的Expires与Cache-control
- TimesTen与Oracle字符集查询
- iOS 开发技巧 更新
- 默认参数
- 20135316王剑桥Linux内核学习记笔记第七周
- WPF TextBox自动滚动到最户一行
- Tcl -- unset
- Nginx性能优化----配置篇
- 第五周项目2-设计游戏角色类
- SpringMVC
- 价值观作业