POJ 1966 Cable TV Network

题意:给出一张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 }
View Code
原文地址:https://www.cnblogs.com/zhexipinnong/p/3388651.html