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

时间:2021-12-09 04:24:38

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也要加上n
121             ans = min(ans, flow);
122         }
123         printf("%d\n",ans);
124     }
125 }