标签:
Time Limit: 3000/2000 MS (Java/Others) Memory Limit: 65535/102400 K (Java/Others)
Total Submission(s): 769 Accepted Submission(s): 340
题意:一无权无向无环无多余边图G,由n个结点,m条边构成。T是其生成树。如果T除去一条边,G有一个割可以代表T,我们这么说。找最小割
输入n, m;前 n -1行代表T,之后m-n+1行是G中T没有的边。求最小割。
割就是,在T中删除一条边,在G中需要删除几条边可以变成T的图的连接关系。在m-n-1行中都是T中没有的边,添加了(u, v)之后,v中的子节点,叶子节点都可以和u联系,那么在求最小割的时候就要删除这条边,使得v中原本不能与u联系的还是不能联系变成 T 图的关系。
用cnt存该点由G变成T(在T中删除一条边)变 了 n-1次(一次删除一条边)之后,需要被删除的次数。遍历求最小值即最小割
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <cmath> 8 #include <stack> 9 #include <cstring> 10 11 using namespace std; 12 13 #define INF 0x3f3f3f3f 14 #define min(a,b) (a<b?a:b) 15 #define N 100005 16 17 vector< vector<int> > G; 18 19 int n, m, cnt[N], dfn[N], f[N]; 20 21 void init() 22 { 23 G.resize(N); 24 G.clear(); 25 memset(dfn, 0, sizeof(dfn)); 26 } 27 28 void Tarjan(int u, int fa, int step) 29 { 30 dfn[u] = step; 31 cnt[u] = 1; 32 f[u] = fa; 33 int len = G[u].size(); 34 for(int i = 0; i < len; i++) 35 { 36 int v = G[u][i]; 37 if(v != fa) 38 Tarjan(v, u, step+1); 39 } 40 } 41 42 void Lca(int x, int y) 43 { 44 while(x != y) 45 { 46 if(dfn[x] >= dfn[y]) //dfn表示树的深度,找深的父节点 47 { 48 cnt[x]++; 49 x = f[x]; 50 } 51 else 52 { 53 cnt[y]++; 54 y = f[y]; 55 } 56 } 57 } 58 59 int main() 60 { 61 int t, i, a, b, l = 1; 62 scanf("%d", &t); 63 while(t--) 64 { 65 init(); 66 scanf("%d%d", &n, &m); 67 for(i = 1; i < n; i++) 68 { 69 scanf("%d%d", &a, &b); 70 G[a].push_back(b); 71 G[b].push_back(a); 72 } 73 Tarjan(1, 0, 1); 74 for(; i <= m; i++) 75 { 76 scanf("%d%d", &a, &b); 77 Lca(a, b); 78 } 79 int ans = INF; 80 for(i = 2; i <= n; i++) 81 ans = min(ans, cnt[i]); 82 printf("Case #%d: %d\n", l++ ,ans); 83 } 84 return 0; 85 }
标签:
原文地址:http://www.cnblogs.com/Tinamei/p/4833417.html