hdu5452 Minimum Cut(最近公共祖先LCA+差分前缀和)
来源:互联网 发布:知乎 小米话题 编辑:程序博客网 时间:2024/04/29 00:38
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 inG 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 graphG respecting the given spanning tree T .
We say that a cut in
Since love needs good faith and hypocrisy return for only grief, you should find the minimum cut of graph
Input
The input contains several test cases.
The first line of the input is a single integert (1≤t≤5) which is the number of test cases.
Thent test cases follow.
Each test case contains several lines.
The first line contains two integersn (2≤n≤20000) and m (n−1≤m≤200000) .
The followingn−1 lines describe the spanning tree T and each of them contains two integers u and v corresponding to an edge.
Nextm−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 .
The first line of the input is a single integer
Then
Each test case contains several lines.
The first line contains two integers
The following
Next
Output
For each test case, you should output the minimum cut of graph G respecting the given spanning tree T .
Sample Input
14 51 22 33 41 31 4
Sample Output
Case #1: 2
http://acm.hdu.edu.cn/showproblem.php?pid=5452
给定一个图的一棵生成树然后给出一些其他的边,没有重边和自环,问在取且仅取一条树边的前提下,图的最小割边的数量是多少?
割边的定义是去掉这几条边可以使连通图不连通。
感觉理解是很重要的,不管是题意还是做法。
对于每条不是树上的边<a, b>, a节点加1, b节点加1,LCA(a, b)减 2,对每颗子树求和。
首先,生成树肯定是一颗经过图中所有点的树。那么,要使图中某两点断连,去掉的边必然包括生成树中的一条或几条边。而题目要求是去且去掉一条,所以可以枚举去掉哪一条树边。
明确w[p]的定义:使p和fa[p]断开所最少需要去掉的非树边的边数。所以没有w[0]。
LCA(a, b)减 2是因为当前枚举的这条去掉的边是不能对LCA(a, b)以及它的父父父…节点造成影响的,在通过dfs函数将子节点值累加到父节点时,+1+1-2,可以消去了。
这个dfs写得真心不错,把原来要用树链剖分还是树形dp的部分直接简化了。
#include<iostream>#include<algorithm>#include<string>#include<map>//int dx[4]={0,0,-1,1};int dy[4]={-1,1,0,0};#include<set>//int gcd(int a,int b){return b?gcd(b,a%b):a;}#include<vector>#include<cmath>#include<queue>#include<string.h>#include<stdlib.h>#include<cstdio>#define mod 1e9+7#define ll long longusing namespace std;vector<int> g[20005],t[20005];int fa[20005],vis[20005],w[20005],minn;int find(int x) { return x==fa[x] ? x : (fa[x] = find(fa[x]));}void lca(int u,int p){for(int i=0;i<t[u].size();++i){int v=t[u][i];if(v!=p){lca(v,u);fa[v]=u; }}vis[u]=1;for(int i=0;i<g[u].size();++i){int v=g[u][i];if(vis[v]==1){w[u]++;w[v]++;w[find(v)]-=2; //为什么find(u)是错的?}}}void dfs(int u,int p){for(int i=0;i<t[u].size();++i){int v=t[u][i];if(v!=p){dfs(v,u);w[u]+=w[v];}}if(u!=0)minn=min(minn,w[u]);}int main(){int tt,cnt=0;scanf("%d",&tt);while(tt--){minn=100000000;int n,m,a,b;scanf("%d%d", &n, &m);memset(w,0,sizeof(w));memset(vis,0,sizeof(vis));for(int i=0;i<n;++i)g[i].clear(),t[i].clear();for(int i=0;i<n;++i)fa[i]=i;for(int i=0;i<n-1;++i){scanf("%d%d", &a, &b);a--;b--;t[a].push_back(b);t[b].push_back(a);}for(int i=n-1;i<m;++i){scanf("%d%d", &a, &b);a--;b--;g[a].push_back(b);g[b].push_back(a);}lca(0,-1);dfs(0,-1);printf("Case #%d: %d\n",++cnt,minn+1);} return 0;}
1 0
- hdu5452 Minimum Cut(最近公共祖先LCA+差分前缀和)
- hdu 5452 Minimum Cut(树链剖分+差分前缀和)
- #HDU5452#Minimum Cut(LCA+树剖)
- hdu5452 离线最近公共祖先
- LCA(最近公共祖先)
- 【最近公共祖先(LCA)】
- 最近公共祖先(LCA)
- 最近公共祖先(LCA)
- LCA(最近公共祖先)
- LCA----【模板】最近公共祖先(LCA)
- HDU5452 Minimum Cut(树链剖分)
- HDU5452 Minimum Cut(图论)
- 最近公共祖先LCA
- 最近公共祖先(LCA)
- Lca 最近公共祖先
- LCA----最近公共祖先
- LCA (最近公共祖先)
- LCA最近公共祖先
- 第一行代码笔记2
- 面对对象思想2
- 汉诺塔
- 带你玩转Visual Studio——带你新建一个工程
- c++设计模式----模板方法template method
- hdu5452 Minimum Cut(最近公共祖先LCA+差分前缀和)
- C# 常用算法
- 【POJ3749】:破译密码
- 和大家分享C语言中几个知识点
- Code Block Evaluation C Extension
- springmvc上传文件
- head first python读书笔记(十)
- 数据缓存
- java面试题九 数组初始化