您的位置:首页 > 其它

HDU 5452 Minimum Cut

2015-09-19 22:54 363 查看

Minimum Cut

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


[align=left]Problem Description[/align]

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.

[align=left]Output[/align]
For each test case, you should output the minimum cut of graph G respecting the given spanning tree T.

[align=left]Sample Input[/align]

1

4 5

1 2

2 3

3 4

1 3

1 4

[align=left]Sample Output[/align]

Case #1: 2

[align=left]Source[/align]
2015 ACM/ICPC Asia Regional Shenyang Online
解题:先把树建好,添加非树边,会形成环,把环上的树边都+1,最后树上的最小边+1就是答案

#include <bits/stdc++.h>
using namespace std;
const int maxn = 20010;
struct arc {
int to,next;
arc(int x = 0,int y = -1) {
to = x;
next = y;
}
} e[500100];
int head[maxn],fa[maxn],top[maxn],de[maxn];
int siz[maxn],son[maxn],loc[maxn],c[maxn],tot,clk;
void add(int u,int v) {
e[tot] = arc(v,head[u]);
head[u] = tot++;
}
void FindHeavyEdge(int u,int father,int depth) {
fa[u] = father;
siz[u] = 1;
son[u] = -1;
de[u] = depth;
for(int i = head[u]; ~i; i = e[i].next) {
if(e[i].to == father) continue;
FindHeavyEdge(e[i].to,u,depth + 1);
siz[u] += siz[e[i].to];
if(son[u] == -1 || siz[e[i].to] > siz[son[u]])
son[u] = e[i].to;
}
}
void ConnectHeavyEdge(int u,int ancestor) {
top[u] = ancestor;
loc[u] = clk++;
if(son[u] != -1) ConnectHeavyEdge(son[u],ancestor);
for(int i = head[u]; ~i; i = e[i].next) {
if(e[i].to == fa[u] || son[u] == e[i].to) continue;
ConnectHeavyEdge(e[i].to,e[i].to);
}
}
void update(int u,int v) {
while(top[u] != top[v]) {
if(de[top[u]] < de[top[v]]) swap(u,v);
c[loc[top[u]]]++;
c[loc[u] + 1]--;
u = fa[top[u]];
}
if(u == v) return;
if(de[u] > de[v]) swap(u,v);
c[loc[son[u]]]++;
c[loc[v]+1]--;
}
int main() {
int kase,u,v,n,m,cs = 1;
scanf("%d",&kase);
while(kase--) {
memset(head,-1,sizeof head);
memset(c,0,sizeof c);
tot = clk = 0;
scanf("%d%d",&n,&m);
for(int i = 1; i < n; ++i) {
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
FindHeavyEdge(1,0,0);
ConnectHeavyEdge(1,1);
for(int i = 0; i <= m - n; ++i) {
scanf("%d%d",&u,&v);
update(u,v);
}
int ret = 0x3f3f3f3f;
for(int i = 1; i < clk; ++i) {
c[i] += c[i-1];
ret = min(ret,c[i]);
}
printf("Case #%d: %d\n",cs++,ret + 1);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: