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 }