题意:给出一张n个点m条边无向图,问最少删几个点使得原图非连通。
无向图不带权的点连通问题。拆点,对每个点i,对应边(i,i',1),对原图中的每条边(i,j),对应两条正向边(i',j,inf),(j',i,inf),选定任意一个源点S',枚举所有汇点T,跑最大流,对最小的最大流ans,如果ans=inf,则答案就是n,否则答案是ans。
代码:
1 #include <iostream> 2 #include <algorithm> 3 #include <queue> 4 #include <cstdio> 5 #include <cstring> 6 #define maxn 110 7 #define inf 1<<30 8 using namespace std; 9 int c[maxn][maxn],f[maxn][maxn],pre[maxn],dis[maxn],num[maxn],cur[maxn]; 10 int s,t,n,m; 11 void bfs() 12 { 13 int u,v,vis[maxn]; 14 memset(dis,0,sizeof(dis)); 15 memset(num,0,sizeof(num)); 16 queue<int> q; 17 q.push(t); 18 vis[t]=0; 19 dis[t]=0; 20 num[0]++; 21 while(!q.empty()) 22 { 23 u=q.front(); 24 q.pop(); 25 for(v=1;v<=2*n;v++) 26 { 27 if(c[v][u]&&!vis[u]) 28 { 29 dis[v]=dis[v]+1; 30 num[dis[v]]++; 31 vis[v]=1; 32 q.push(v); 33 } 34 } 35 } 36 } 37 int sap() 38 { 39 int u,v,i,aug=inf,flag,flow=0; 40 for(i=1;i<=2*n;i++) 41 { 42 dis[i]=num[i]=0; 43 cur[i]=1; 44 } 45 bfs(); 46 u=s; 47 num[0]=2*n; 48 while(dis[s]<2*n) 49 { 50 flag=0; 51 for(v=cur[u];v<=2*n;v++) 52 { 53 if(c[u][v]>f[u][v]&&dis[u]==dis[v]+1) 54 { 55 flag=1; 56 pre[v]=u; 57 cur[u]=v; 58 aug=min(aug,c[u][v]-f[u][v]); 59 u=v; 60 if(u==t) 61 { 62 flow+=aug; 63 while(u!=s) 64 { 65 f[pre[u]][u]+=aug; 66 f[u][pre[u]]-=aug; 67 u=pre[u]; 68 } 69 aug=inf; 70 u=s; 71 } 72 break; 73 } 74 } 75 if(flag) 76 continue; 77 if(--num[dis[u]]==0) 78 return flow; 79 dis[u]=inf; 80 for(v=1;v<=2*n;v++) 81 { 82 if(c[u][v]>f[u][v]&&dis[v]<dis[u]) 83 { 84 dis[u]=dis[v]; 85 cur[u]=v; 86 } 87 } 88 dis[u]++; 89 num[dis[u]]++; 90 if(u!=s) 91 u=pre[u]; 92 } 93 return flow; 94 } 95 96 int main(){ 97 while(scanf("%d%d",&n,&m) != EOF){ 98 memset(c,0,sizeof(c)); 99 for(int i = 0;i < m;i++){ 100 int a,b; 101 scanf(" (%d,%d)",&a,&b); 102 c[a+n+1][b+1] = c[b+n+1][a+1] = inf; 103 } 104 for(int i = 0;i < n;i++){ 105 c[i+1][i+n+1] = 1; 106 } 107 int ans = inf; 108 for(int i = 1;i < n;i++){ 109 s = n+1,t = i+1; 110 memset(f,0,sizeof(f)); 111 int tmp = sap(); 112 if(tmp < ans) ans = tmp; 113 } 114 if(ans >= inf) printf("%d ",n); 115 else printf("%d ",ans); 116 } 117 return 0; 118 }