POJ 1966 Cable TV Network(证明有误)
2010-12-21 19:21
246 查看
求图的点连通度
点连通度的定义:一个具有N个点的图G中,在去掉任意k-1个顶点后(1<=k<=N),所得的子图仍然连通,去掉K个顶点后不连通,则称G是K连通图,K称作图G的连通度,记作K(G)。即去掉最少个数的点后,子图不连通或者成为平凡图
做法:拆点(无向无向边拆成两条有向边),指定一个源点,枚举汇点(如果汇点与源点不连通,则图不连通),求使源汇不连通最少要移除的点数,并取最小值,如果最小值比n大,则最小值为n
详情见:http://hi.baidu.com/lerroy312/blog/item/d7ea97ee7b1f3cddd439c927.html
对于为什么只要枚举汇点:
假设点连通度为k,那么如果你枚举源汇,我们构图的时候是拆点的,所有最小割中最小的一定是k,对应k个点,割边为这k个点拆点后对应的边,那么,这个最小割把所有点点分成了两部分,S和T集合,S和T集合中的点都是不连通的,而S集合中的点都是连通的,T集合中的点也都是连通的,对于任意一个点i属于S,任意一个点j属于T,要使得他们不连通,在图中删除的点都为k,不可能更小了,否则最小割值比k小,而如果他们同时属于S集合或者T集合,使得他们不连通,要删除的点大于k,因为他们现在还连通,于是,如果我们指定一个源点,枚举汇点,如果这个源点与汇点同时在刚才那个最小割的S或T集合中,要使他们不连通,删除的点必然大于k,如果他们一个属于S,一个属于T,那么使他们不连通,要删除的点就是k个,所以,只要枚举汇点就行了
代码:
点连通度的定义:一个具有N个点的图G中,在去掉任意k-1个顶点后(1<=k<=N),所得的子图仍然连通,去掉K个顶点后不连通,则称G是K连通图,K称作图G的连通度,记作K(G)。即去掉最少个数的点后,子图不连通或者成为平凡图
做法:拆点(无向无向边拆成两条有向边),指定一个源点,枚举汇点(如果汇点与源点不连通,则图不连通),求使源汇不连通最少要移除的点数,并取最小值,如果最小值比n大,则最小值为n
详情见:http://hi.baidu.com/lerroy312/blog/item/d7ea97ee7b1f3cddd439c927.html
对于为什么只要枚举汇点:
假设点连通度为k,那么如果你枚举源汇,我们构图的时候是拆点的,所有最小割中最小的一定是k,对应k个点,割边为这k个点拆点后对应的边,那么,这个最小割把所有点点分成了两部分,S和T集合,S和T集合中的点都是不连通的,而S集合中的点都是连通的,T集合中的点也都是连通的,对于任意一个点i属于S,任意一个点j属于T,要使得他们不连通,在图中删除的点都为k,不可能更小了,否则最小割值比k小,而如果他们同时属于S集合或者T集合,使得他们不连通,要删除的点大于k,因为他们现在还连通,于是,如果我们指定一个源点,枚举汇点,如果这个源点与汇点同时在刚才那个最小割的S或T集合中,要使他们不连通,删除的点必然大于k,如果他们一个属于S,一个属于T,那么使他们不连通,要删除的点就是k个,所以,只要枚举汇点就行了
代码:
#include<iostream> #include<cstdio> #include<memory.h> #include<algorithm> using namespace std; const int inf=1<<29; const int MAX=105; int c[MAX][MAX],f[MAX][MAX],pre[MAX],q[MAX],rc[MAX]; int n,m,s,t,max_flow; bool bfs() { int i,j,tail=1,head=0; memset(rc,0,sizeof(rc)); q[tail]=s; pre[s]=-1; rc[s]=inf; while(head<tail) { i=q[++head]; for(j=1;j<=n*2;j++) { if(c[i][j]>f[i][j]&&!rc[j]) { rc[j]=min(rc[i],c[i][j]-f[i][j]); pre[j]=i; q[++tail]=j; if(j==t) return true; } } } return false; } int EK() { int i; max_flow=0; while(bfs()) { for(i=t;i!=s;i=pre[i]) { f[pre[i]][i]+=rc[t];//加减别搞反了 f[i][pre[i]]-=rc[t]; } max_flow+=rc[t]; } return max_flow; } int main() { int i,j,a,b,ans,flow; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0) { puts("0"); continue; } memset(c,0,sizeof(c)); for(i=1;i<=n;i++) c[i][i+n]=1; for(i=1;i<=m;i++) { scanf(" (%d,%d)",&a,&b); c[a+1+n][b+1]=inf; c[b+1+n][a+1]=inf; } ans=inf; s=n+1; for(i=2;i<=n;i++) { memset(f,0,sizeof(f)); t=i; flow=EK(); cout<<"flow="<<flow<<endl; if(flow<ans) ans=flow; } if(ans==inf)//构图局限性,最多只能删除n-1个点,而有些图必须删除n个点 ans=n; cout<<ans<<endl; } return 0; }
相关文章推荐
- poj 1966 Cable TV Network 顶点连通度-最大流
- POJ 1966 Cable TV Network 顶点连通度的求解
- POJ 1966 Cable TV Network【无向图点连通度 最小割 E-K算法求最大流】
- POJ1966 Cable TV Network
- POJ--1966--Cable TV Network【无向图顶点连通度】
- 【连通图|点连通度】POJ-1966 Cable TV Network
- POJ 1966 Cable TV Network (用最大流求最小割点数量)
- poj 1966 Cable TV Network 【枚举源汇 求解 无向图最小割】
- POJ 1966 Cable TV Network 最小割
- POJ 1966 Cable TV Network【SAP】
- Cable TV Network- POJ 1966 连通量
- POJ 1966 Cable TV Network
- poj 1966 zoj 2182 Cable TV Network(无向图顶点连通度(sap求最大流))
- POJ1966--Cable TV Network
- POJ 1966 Cable TV Network
- POJ 1966 Cable TV Network 笔记
- poj 1966 Cable TV Network 顶点连通度
- POJ 1966 Cable TV Network
- POJ 1966 Cable TV Network(顶点连通度)
- POJ 1966--Cable TV Network【最小割 && 枚举终点起点】