给一个图, n个点m条边, 求至少去掉多少个点可以使得图不再联通。
随便指定一个点为源点, 枚举其他点为汇点的情况, 跑网络流, 求其中最小的情况。 如果最后ans为inf, 说明是一个完全图, 那么结果就为n。
1 #include <iostream> 2 #include <vector> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #include <cmath> 7 #include <map> 8 #include <set> 9 #include <string> 10 #include <queue> 11 using namespace std; 12 #define pb(x) push_back(x) 13 #define ll long long 14 #define mk(x, y) make_pair(x, y) 15 #define lson l, m, rt<<1 16 #define mem(a) memset(a, 0, sizeof(a)) 17 #define rson m+1, r, rt<<1|1 18 #define mem1(a) memset(a, -1, sizeof(a)) 19 #define mem2(a) memset(a, 0x3f, sizeof(a)) 20 #define rep(i, a, n) for(int i = a; i<n; i++) 21 #define ull unsigned long long 22 typedef pair<int, int> pll; 23 const double PI = acos(-1.0); 24 const double eps = 1e-8; 25 const int mod = 1e9+7; 26 const int inf = 1061109567; 27 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; 28 const int maxn = 4e4+5; 29 int q[maxn*2], head[maxn*2], dis[maxn/10], s, t, num, edge[2500][2]; 30 struct node 31 { 32 int to, nextt, c; 33 node(){} 34 node(int to, int nextt, int c):to(to), nextt(nextt), c(c){} 35 }e[maxn*2]; 36 void init() { 37 num = 0; 38 mem1(head); 39 } 40 void add(int u, int v, int c) { 41 e[num] = node(v, head[u], c); head[u] = num++; 42 e[num] = node(u, head[v], 0); head[v] = num++; 43 } 44 int bfs() { 45 mem(dis); 46 dis[s] = 1; 47 int st = 0, ed = 0; 48 q[ed++] = s; 49 while(st<ed) { 50 int u = q[st++]; 51 for(int i = head[u]; ~i; i = e[i].nextt) { 52 int v = e[i].to; 53 if(!dis[v]&&e[i].c) { 54 dis[v] = dis[u]+1; 55 if(v == t) 56 return 1; 57 q[ed++] = v; 58 } 59 } 60 } 61 return 0; 62 } 63 int dfs(int u, int limit) { 64 if(u == t) { 65 return limit; 66 } 67 int cost = 0; 68 for(int i = head[u]; ~i; i = e[i].nextt) { 69 int v = e[i].to; 70 if(e[i].c&&dis[v] == dis[u]+1) { 71 int tmp = dfs(v, min(limit-cost, e[i].c)); 72 if(tmp>0) { 73 e[i].c -= tmp; 74 e[i^1].c += tmp; 75 cost += tmp; 76 if(cost == limit) 77 break; 78 } else { 79 dis[v] = -1; 80 } 81 } 82 } 83 return cost; 84 } 85 int dinic() { 86 int ans = 0; 87 while(bfs()) { 88 ans += dfs(s, inf); 89 } 90 return ans; 91 } 92 int main() 93 { 94 int n, m, x, y; 95 while(~scanf("%d%d", &n, &m)) { 96 for(int i = 0; i<m; i++) { 97 scanf(" (%d,%d)", &edge[i][0], &edge[i][1]); 98 } 99 s = n; 100 int ans = inf; 101 for(int i = 1; i<n; i++) { 102 t = i; 103 init(); 104 for(int j = 0; j<m; j++) { 105 int x = edge[j][0]; 106 int y = edge[j][1]; 107 add(x+n, y, inf); 108 add(y+n, x, inf); 109 } 110 for(int j = 0; j<n; j++) 111 add(j, j+n, 1); 112 ans = min(ans, dinic()); 113 } 114 if(ans == inf) 115 ans = n; 116 cout<<ans<<endl; 117 } 118 return 0; 119 }
时间: 2024-10-22 16:04:15