求顶点连通度的方法 :
(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 ",ans); 111 } 112 return 0; 113 }