POJ1966 ZOJ2182<无向图点连通度 Isap版>

求顶点连通度的方法 :
(1)把原图中每个结点拆成2个结点v1,v2,顶点v1到v2有一条弧<v1,v2>,容量为1
(2)对于原图中每条边e(u,v);在网络中有两条弧e1=<u2,v1> ,e2=<u1,v2>容量都为inf
(3)固定源点A2,枚举每个汇点(原图中不与A点相邻的),记录最小独立轨数目,该值就是顶点连通度

刚刚看到这位大神的博客,才知道固定一个源点的做法是错误的。。

地址:http://www.cnblogs.com/wuyiqi/archive/2011/10/09/2203516.html

固定一个源点的做法是错误的,因为如果刚好枚举的源点是割顶集里面的点就不行了
如如下数据5 6 (0,1) (0,2) (1,2) (0,3) (0,4) (3,4)
答案应该是1
但如果没有两两枚举源点汇点,答案就成了5了
所以,还是要两两枚举点的 

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 using namespace std;
  7 #define inf 0x7fffffff
  8 #define N 105
  9 #define M 10005
 10 int cur[N],gap[N],pre[N],dis[N];
 11 int size,head[N];
 12 bool s[N][N];
 13 struct Edge
 14 {
 15     int v,w,next;
 16     Edge(){}
 17     Edge(int V,int W,int NEXT):v(V),w(W),next(NEXT){}
 18 }edge[M];
 19 
 20 void InsertEdge(int u,int v,int w)
 21 {
 22     edge[size] = Edge(v,w,head[u]);
 23     head[u] = size++;
 24     edge[size] = Edge(u,0,head[v]);
 25     head[v] = size++;
 26 }
 27 void Init(int n)
 28 {
 29     size = 0;
 30     memset(head,-1,sizeof(head));
 31     for(int j=0; j<n; j++)
 32     InsertEdge(j,j+n,1);
 33     for(int j=0; j<n; j++)
 34     for(int k=j+1; k<n; k++)
 35     {
 36         if(s[j][k])
 37         {
 38             InsertEdge(j+n,k,inf);
 39             InsertEdge(k+n,j,inf);
 40         }
 41     }
 42 }
 43 int Isap(int st,int ed,int n) { //Isap模板 
 44     for(int i=0; i<=n; i++) {
 45         cur[i] = head[i];
 46         gap[i] = dis[i] = 0;
 47     }
 48     int u = pre[st] = st;
 49     int aug = inf ,maxflow = 0;
 50     while(dis[st] < n) {
 51 loop:
 52         for(int &i=cur[u]; i!=-1; i=edge[i].next) {
 53             int v = edge[i].v;
 54             if(edge[i].w && dis[u] == dis[v] + 1) {
 55                 aug = min(aug,edge[i].w);
 56                 pre[v] = u;
 57                 u = v;
 58                 if(v==ed) {
 59                     maxflow += aug;
 60                     for(u=pre[u]; v!=st; v=u,u=pre[u]) {
 61                         edge[cur[u]].w -= aug;
 62                         edge[cur[ u]^1].w += aug;
 63                     }
 64                     aug = inf;
 65                 }
 66                 goto loop;
 67             }
 68         }
 69         int mindis = n;
 70         for(int i=head[u]; i!=-1; i=edge[i].next) {
 71             int v = edge[i].v;
 72             if(edge[i].w && dis[v]<mindis) {
 73                 cur[u] = i;
 74                 mindis = dis[v];
 75             }
 76         }
 77         if(--gap[dis[u]]==0) break;
 78         gap[dis[u] = mindis+1]++;
 79         u = pre[u];
 80     }
 81     return maxflow;
 82 }
 83 
 84 int main()
 85 {
 86     int n,m,nv;
 87     while(scanf("%d%d",&n,&m)!=EOF)
 88     {
 89         nv = 2*n;
 90         for(int i=0; i<n; i++)
 91         for(int j=0; j<n; j++)
 92         s[i][j] = i==j;
 93         for(int i=0; i<m; i++)
 94         {
 95             int u,v;
 96             scanf(" (%d,%d)",&u,&v);
 97             s[u][v] = s[v][u] = 1;
 98         }
 99         int ans = inf;
100         for(int i=0; i<n; i++) 
101         {
102             for(int j=0; j<n; j++)
103             {
104                 if(s[i][j]) continue;
105                 Init(n);
106                 ans = min(ans,Isap(i+n,j,nv));
107             }
108         }
109         if(ans == inf)ans = n;
110         printf("%d\n",ans);
111     }
112     return 0;
113 }
View Code

 

 

posted on 2013-08-21 15:31  爱∪  阅读(291)  评论(0)    收藏  举报

导航