码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5452 Minimum Cut

时间:2015-09-20 00:00:24      阅读:643      评论:0      收藏:0      [点我收藏+]

标签:

Minimum Cut

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


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 (1≤t≤5) 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 (2≤n≤20000) and m (n−1≤m≤200000).
The following n−1 lines describe the spanning tree T and each of them contains two integers u and v corresponding to an edge.
Next m−n+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

 解题:先把树建好,添加非树边,会形成环,把环上的非树边都+1,最后树上的最小边+1就是答案

技术分享
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 20010;
 4 struct arc {
 5     int to,next;
 6     arc(int x = 0,int y = -1) {
 7         to = x;
 8         next = y;
 9     }
10 } e[500100];
11 int head[maxn],fa[maxn],top[maxn],de[maxn];
12 int siz[maxn],son[maxn],loc[maxn],c[maxn],tot,clk;
13 void add(int u,int v) {
14     e[tot] = arc(v,head[u]);
15     head[u] = tot++;
16 }
17 void FindHeavyEdge(int u,int father,int depth) {
18     fa[u] = father;
19     siz[u] = 1;
20     son[u] = -1;
21     de[u] = depth;
22     for(int i = head[u]; ~i; i = e[i].next) {
23         if(e[i].to == father) continue;
24         FindHeavyEdge(e[i].to,u,depth + 1);
25         siz[u] += siz[e[i].to];
26         if(son[u] == -1 || siz[e[i].to] > siz[son[u]])
27             son[u] = e[i].to;
28     }
29 }
30 void ConnectHeavyEdge(int u,int ancestor) {
31     top[u] = ancestor;
32     loc[u] = clk++;
33     if(son[u] != -1) ConnectHeavyEdge(son[u],ancestor);
34     for(int i = head[u]; ~i; i = e[i].next) {
35         if(e[i].to == fa[u] || son[u] == e[i].to) continue;
36         ConnectHeavyEdge(e[i].to,e[i].to);
37     }
38 }
39 void update(int u,int v) {
40     while(top[u] != top[v]) {
41         if(de[top[u]] < de[top[v]]) swap(u,v);
42         c[loc[top[u]]]++;
43         c[loc[u] + 1]--;
44         u = fa[top[u]];
45     }
46     if(u == v) return;
47     if(de[u] > de[v]) swap(u,v);
48     c[loc[son[u]]]++;
49     c[loc[v]+1]--;
50 }
51 int main() {
52     int kase,u,v,n,m,cs = 1;
53     scanf("%d",&kase);
54     while(kase--) {
55         memset(head,-1,sizeof head);
56         memset(c,0,sizeof c);
57         tot = clk = 0;
58         scanf("%d%d",&n,&m);
59         for(int i = 1; i < n; ++i) {
60             scanf("%d%d",&u,&v);
61             add(u,v);
62             add(v,u);
63         }
64         FindHeavyEdge(1,0,0);
65         ConnectHeavyEdge(1,1);
66         for(int i = 0; i <= m - n; ++i) {
67             scanf("%d%d",&u,&v);
68             update(u,v);
69         }
70         int ret = 0x3f3f3f3f;
71         for(int i = 1; i < clk; ++i) {
72             c[i] += c[i-1];
73             ret = min(ret,c[i]);
74         }
75         printf("Case #%d: %d\n",cs++,ret + 1);
76     }
77     return 0;
78 }
View Code

 

HDU 5452 Minimum Cut

标签:

原文地址:http://www.cnblogs.com/crackpotisback/p/4822479.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!