Tinamei
其实你不知道你不知道

Minimum Cut

Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)
Total Submission(s): 769    Accepted Submission(s): 340


Problem Description
Given a simple unweighted graph G (an undirected graph containing no loops nor multiple edges) with n nodes and m edges. Let T be a spanning tree of G.
We say that a cut in G respects T if it cuts just one edges of T.

Since love needs good faith and hypocrisy return for only grief, you should find the minimum cut of graph G respecting the given spanning tree T.
 

 

Input
The input contains several test cases.
The first line of the input is a single integer t (1t5) which is the number of test cases.
Then t test cases follow.

Each test case contains several lines.
The first line contains two integers n (2n20000) and m (n1m200000).
The following n1 lines describe the spanning tree T and each of them contains two integers u and v corresponding to an edge.
Next mn+1 lines describe the undirected graph G and each of them contains two integers u and v corresponding to an edge which is not in the spanning tree T.
 

 

Output
For each test case, you should output the minimum cut of graph G respecting the given spanning tree T.
 

 

Sample Input
1
4 5
1 2
2 3
3 4
1 3
1 4
 

 

Sample Output
Case #1: 2
 

 

Source
 
题意:在G中有T,问G 最小割中有且仅有一割在 T  中的最小割是多少。
 

考虑每条不属 于 T   边  对 生成树 T  树 边 的覆盖次数。

每条树边被覆盖的次数其实就是断裂这条树边后还需断裂的新边数。

 
在m-n-1行中都是T中没有的边,添加了(u, v)之后,v中的子节点,叶子节点都可以和u联系,那么在求最小割的时候就要删除这条边,使得G中 变成两个由 u 和v 构成的不连通的图。

用cnt 存该点需要被断裂几次,即断裂这条边后 还需要断裂几条边可以使G 不连通。遍历求最小值即最小割

 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 int deep[N], f[N], cnt[N];
19 
20 void dfs(int u, int fa, int step)
21 {
22     deep[u] = step;
23     cnt[u] = 1;
24     f[u] = fa;
25     int len = G[u].size();
26     for(int i = 0; i < len; i++)
27     {
28         int v = G[u][i];
29         if(v != fa)
30             dfs(v, u, step+1);
31     }
32 }
33 
34 void Lca(int x, int y)
35 {
36     while(x != y)
37     {
38         if(deep[x] >= deep[y])
39         {
40             cnt[x]++;
41             x = f[x];
42         }
43         else
44         {
45             cnt[y]++;
46             y = f[y];
47         }
48     }
49 }
50 
51 int main()
52 {
53     int t, i, a, b, n, m, l = 1;
54     scanf("%d", &t);
55     while(t--)
56     {
57         G.resize(N);
58         G.clear();
59         scanf("%d%d", &n, &m);
60         for(i = 1; i < n; i++)
61         {
62             scanf("%d%d", &a, &b);
63             G[a].push_back(b);
64             G[b].push_back(a);
65         }
66         dfs(1, 0, 1);
67         for(; i <= m; i++)
68         {
69             scanf("%d%d", &a, &b);
70             Lca(a, b);
71         }
72         int ans = INF;
73         for(i = 2; i <= n; i++)
74             ans = min(ans, cnt[i]);
75         printf("Case #%d: %d\n", l++, ans);
76     }
77     return 0;
78 }

 

posted on 2015-09-23 20:17  Tinamei  阅读(439)  评论(0)    收藏  举报