网络流之顶点连通度 poj 1966 zoj 2182

顶点连通度:即最少去掉几个点使得图不连通

设想两个不相邻的点u,v;

从u到v的两条没有公共内部顶点的路径,互称为独立轨,;u到v独立轨最大的条数,记作P(u,v)

所以要想图不联通,应该在每条独立轨上都去掉一个点(不能随便去),所以顶点连通度就是最大独立轨数目的最小值

注意,如果图是完全图,应该去掉所有的点

怎么求两点间(A,B)的最大独立轨P(A,B)呢?

1、把每个点都拆成两个点,之间连一条容量为1的边u'---u",原图中的每条边e=(u,v)在新网络中有两条弧e'=<u",v'>和e"=<v",u'>,两条边容量均为无穷大

2、设A“为源点,B‘为汇点

3、求两点间的最大流

流出A"的一切弧的流量和就为P(A,B) ,所有具有流量1的弧(此时的弧相当于一个点)对应的顶点构成了一个割顶集,在图中去掉这些点后,A、B就断开了

考虑再三,并经过数据验证,书上应该是错了,要两两枚举源点和汇点

因为如果刚好枚举的源点是割顶集里面的点就不行了

如如下数据5 6 (0,1) (0,2) (1,2) (0,3) (0,4) (3,4)

答案应该是1

但如果没有两两枚举源点汇点,答案就成了5了

所以,还是要两两枚举点的

View Code
#include<stdio.h>
#include<string.h>
const int MAX=100005;
const int INF=1000000000;

struct
{
int v,c,next;
}edge[1000000];
int E,head[MAX];
int gap[MAX],cur[MAX];
int pre[MAX],dis[MAX];
void add_edge(int s,int t,int c,int cc)
{
/*加边的时候同时加两条,
一条正的,一条反的,
一般情况下反的容量是0
*/
edge[E].v=t; edge[E].c=c;
edge[E].next=head[s];
head[s]=E++;
edge[E].v=s; edge[E].c=cc;
edge[E].next=head[t];
head[t]=E++;
}
int min(int a,int b){return (a==-1||b<a)?b:a;}
int SAP(int s,int t,int n)
{}
void init()
{
for(int i=0;i<E;i+=2)
{
edge[i].c+=edge[i^1].c;
edge[i^1].c=0;
}
}
int main()
{
int i,j;
int a,b,n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(head,-1,sizeof(head));E=0;
for(i=0;i<n;i++)
{
add_edge(i,i+n,1,0);
}
for(i=0;i<m;i++)
{
scanf(" (%d,%d)",&a,&b);
add_edge(a+n,b,INF,0);
add_edge(b+n,a,INF,0);
}
int ans=INF;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(j!=i){
int tmp=SAP(i+n,j,2*n);init();
ans=tmp<ans?tmp:ans;
}
}
}
if(ans>=INF) ans=n;
printf("%d\n",ans);
}
return 0;
}



posted @ 2011-10-09 12:44  Because Of You  Views(637)  Comments(1Edit  收藏  举报