首页 > 代码库 > UVa 1660 电视网络(点连通度+最小割最大流+Dinic)

UVa 1660 电视网络(点连通度+最小割最大流+Dinic)

https://vjudge.net/problem/UVA-1660

题意:
给出一个无向图,求出点连通度。即最少删除多少个点,使得图不连通。

 

思路:

如果求线连通度的话,直接求个最大流就可以了。但这题我们删除的是点,用拆点法来使点具有流量的性质,把每个点都拆分为两个点,容量为1,表示可以使用一次。然后,题目中给出的连通的点之间的容量设为INF,因为我们不是要删除这两点之间的线。

最后,我们固定一个源点,枚举汇点,找到最小的删除数。

  1 #include<iostream>   2 #include<algorithm>  3 #include<cstring>  4 #include<string>  5 #include<vector>  6 #include<queue>  7 using namespace std;  8   9 const int maxn = 105; 10 const int INF = 0x3f3f3f3f; 11  12 struct Edge 13 { 14     int from,to, cap, flow; 15     Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f){} 16 }; 17  18 int n, m,t; 19 vector<Edge> edges; 20 vector<Edge> edge; 21 vector<int> G[maxn]; 22 int vis[maxn]; 23 int d[maxn];   //从起点到i的距离 24 int cur[maxn]; //当前弧下标 25 int flow; 26  27 void init() 28 { 29     for (int i = 0; i < maxn; i++) 30         G[i].clear(); 31     edges.clear(); 32 } 33  34 void AddEdge(int from, int to, int cap) 35 { 36     edges.push_back(Edge(from, to, cap, 0)); 37     edges.push_back(Edge(to, from, 0, 0)); 38     int m = edges.size(); 39     G[from].push_back(m - 2); 40     G[to].push_back(m - 1); 41 } 42  43  44 int BFS(int s,int t) 45 { 46     memset(vis, 0, sizeof(vis)); 47     memset(d, 0, sizeof(d)); 48     queue<int> Q; 49     Q.push(s); 50     d[s] = 0; 51     vis[s] = 1; 52     while (!Q.empty()) 53     { 54         int x = Q.front(); 55         Q.pop(); 56         for (int i = 0; i < G[x].size(); i++) 57         { 58             Edge& e = edges[G[x][i]]; 59             if (!vis[e.to] && e.cap>e.flow) 60             { 61                 vis[e.to] = 1; 62                 d[e.to] = d[x] + 1; 63                 Q.push(e.to); 64             } 65         } 66     } 67     return vis[t]; 68 } 69  70 int DFS(int x,int t,int a) 71 { 72     if (x == t || a == 0)  return a; 73     int flow = 0, f; 74     for (int& i = cur[x]; i < G[x].size(); i++) 75     { 76         Edge& e = edges[G[x][i]]; 77         if (d[x] + 1 == d[e.to] && (f = DFS(e.to,t ,min(a,e.cap - e.flow)))>0) 78         { 79             e.flow += f; 80             edges[G[x][i] ^ 1].flow -= f; 81             flow += f; 82             a -= f; 83             if (a == 0)  break; 84         } 85     } 86     return flow; 87 } 88  89 void Maxflow(int s,int t) 90 { 91     flow = 0; 92     while (BFS(s,t)) 93     { 94         memset(cur, 0, sizeof(cur)); 95         flow += DFS(s, t,INF); 96     } 97 } 98  99 int main()100 {101     //freopen("D:\\txt.txt", "r", stdin);102     int x,y;103     while (~scanf("%d%d",&n,&m))104     {105         init();106         for (int i = 1; i < n; i++)107             AddEdge(i, i + n, 1);108         for (int i = 0; i < m; i++)109         {110             scanf(" (%d,%d)", &x, &y);111             AddEdge(x + n, y, INF);112             AddEdge(y + n, x, INF);113         }114         edge = edges;115         flow = 0;116         int ans = n;117         for (int i = 1; i < n; i++)118         {119             edges = edge;     //这个不能忘120             Maxflow(n, i);    //0为源点,因为前面都加了n,所以这里0也要加上n121             ans = min(ans, flow);122         }123         printf("%d\n",ans);124     }125 }

 

UVa 1660 电视网络(点连通度+最小割最大流+Dinic)