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
相关文章推荐
- 新浪、万网前系统架构师高俊峰:统一监控报警平台架构设计思路
- 读写分离之Amoeba
- 简洁调用字号
- 安倍强行通过安保法案带来三大祸害
- codevs 1046 旅行家的预算
- 软工视频(前三章)
- hdu3499 分层图
- 再读大道至简第一章以及生活有感
- Mac OS系统上用命令行方式启动VNC Server
- 第一次博客
- 我的首篇CSDN博客
- 点击UICollectionViewCell上的UIButton如何获取当前的UICollectionViewCell?
- 仿射空间(affine space),仿射组合(affine combination)
- 十六进制颜色宏
- json对象和json字符串有啥区别啊
- 【Xamarin 开发 IOS --使用 Storyboard Segue 实作 UIViewController 的切换 (实例)】
- 各种排序算法的实现Java
- BestCoder Round #56 (div.2)(Clarke and minecraft)
- opencv训练分类器(HAAR,LBP等特征)
- hdu 5452 Minimum Cut 树形dp