http://poj.org/problem?id=1966
这里是点连通度的一些介绍:
//#pragma comment(linker,"/STACK:327680000,327680000") #include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define inf 0x7f7f7f7f #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define ll long long #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x)int #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("din.txt", "r", stdin) #define Write() freopen("dout.txt", "w", stdout); #define N 1005 using namespace std; struct node { int v,w; int next; }g[N*N*2];//开始这里边开小了wa多次,郁闷啊 int head[N],ct; int hash[N][N]; int tab[N][2]; int level[N],q[1000004]; int n,m; void add(int u,int v,int w) { g[ct].v = v; g[ct].w = w; g[ct].next = head[u]; head[u] = ct++; g[ct].v = u; g[ct].w = 0; g[ct].next = head[v]; head[v] = ct++; } //关键是建图 void build(int x,int y) { int i; CL(head,-1); ct = 0; //拆点边权为1 for (i = 1; i <= n; ++i) add(i,i + n,1); //原图中的边,边权为inf for (i = 0; i < m; ++i) { add(tab[i][0] + n,tab[i][1],inf); add(tab[i][1] + n,tab[i][0],inf); } //这里不是很理解...... add(x,x + n,inf); add(y,y + n,inf); } bool layer(int s,int e) { int i; CL(level,-1); queue<int>q; q.push(s); level[s] = 1; while (!q.empty()) { int u = q.front(); q.pop(); for (i = head[u]; i != -1; i = g[i].next) { int v = g[i].v; int w = g[i].w; if (w > 0 && level[v] == -1) { level[v] = level[u] + 1; if (v == e) return true; q.push(v); } } } return false; } int find(int s,int e) { int i; int top = 1,u; int ans = 0; while (top) { if (top == 1) u = s; else u = g[q[top - 1]].v; if (u == e) { int MIN = inf,pos = 0; for (i = 1; i <= top - 1; ++i) { if (MIN > g[q[i]].w) { MIN = g[q[i]].w; pos = i; } } for (i = 1; i <= top - 1; ++i) { g[q[i]].w -= MIN; g[q[i]^1].w += MIN; } ans += MIN; top = pos; } else { for (i = head[u]; i != -1; i = g[i].next) { int w = g[i].w; int v = g[i].v; if (level[v] == level[u] + 1 && w > 0) { q[top++] = i; break; } } if (i == -1) { top--; level[u] = -1; } } } return ans; } int dinic(int s,int e) { int ans = 0; while (layer(s,e)) ans += find(s,e); return ans; } int main() { Read(); int i,j; int x,y; while (~scanf("%d%d",&n,&m)) { if (m == 0) { if (n == 1) printf("1\n"); else printf("0\n"); continue; } CL(hash,0); for (i = 0; i < m; ++i) { scanf(" (%d,%d)",&x,&y); x++; y++; tab[i][0] = x; tab[i][1] = y; hash[x][y] = 1; } int ans = inf; int sign = 0;//如果全部联通的话该图为强连通图,那么它的点连通度为n for (i = 1; i <= n; ++i) { for (j = i + 1; j <= n; ++j) { if (!hash[i][j]) { sign = 1; build(i,j); int res = dinic(i,j + n); ans = min(ans,res); } } } if (!sign) printf("%d\n",n); else printf("%d\n",ans); } return 0; }