POJ 1655.Balancing Act-树的重心(DFS) 模板(vector存图)
Posted zero-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1655.Balancing Act-树的重心(DFS) 模板(vector存图)相关的知识,希望对你有一定的参考价值。
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 17497 | Accepted: 7398 |
Description
Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. Deleting any node from the tree yields a forest: a collection of one or more trees. Define the balance of a node to be the size of the largest tree in the forest T created by deleting that node from T.
For example, consider the tree:
Deleting node 4 yields two trees whose member nodes are {5} and {1,2,3,6,7}. The larger of these two trees has five nodes, thus the balance of node 4 is five. Deleting node 1 yields a forest of three trees of equal size: {2,6}, {3,7}, and {4,5}. Each of these trees has two nodes, so the balance of node 1 is two.
For each input tree, calculate the node that has the minimum balance. If multiple nodes have equal balance, output the one with the lowest number.
For example, consider the tree:
Deleting node 4 yields two trees whose member nodes are {5} and {1,2,3,6,7}. The larger of these two trees has five nodes, thus the balance of node 4 is five. Deleting node 1 yields a forest of three trees of equal size: {2,6}, {3,7}, and {4,5}. Each of these trees has two nodes, so the balance of node 1 is two.
For each input tree, calculate the node that has the minimum balance. If multiple nodes have equal balance, output the one with the lowest number.
Input
The first line of input contains a single integer t (1 <= t <= 20), the number of test cases. The first line of each test case contains an integer N (1 <= N <= 20,000), the number of congruence. The next N-1 lines each contains two space-separated node numbers that are the endpoints of an edge in the tree. No edge will be listed twice, and all edges will be listed.
Output
For each test case, print a line containing two integers, the number of the node with minimum balance and the balance of that node.
Sample Input
1 7 2 6 1 2 1 4 4 5 3 7 3 1
Sample Output
1 2
Source
题意就是找树的重心,然后通过树的重心的概念,找到树的重心,删掉之后子树是最平衡的。直接贴的模板。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<bitset> 6 #include<cassert> 7 #include<cctype> 8 #include<cmath> 9 #include<cstdlib> 10 #include<ctime> 11 #include<deque> 12 #include<iomanip> 13 #include<list> 14 #include<map> 15 #include<queue> 16 #include<set> 17 #include<stack> 18 #include<vector> 19 using namespace std; 20 typedef long long ll; 21 typedef long double ld; 22 typedef pair<int,int> pii; 23 24 const double PI=acos(-1.0); 25 const double eps=1e-6; 26 const ll mod=1e9+7; 27 const int inf=0x3f3f3f3f; 28 const int maxn=1e5+10; 29 const int maxm=100+10; 30 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); 31 32 int n,father; 33 int siz[maxn];//siz保存每个节点的子树大小 34 bool vist[maxn]; 35 int point=inf,minsum=-1;//minsum表示切掉重心后最大连通块的大小 36 vector<int>G[maxn]; 37 38 void DFS(int u,int x)//遍历到节点x,x的父亲是u 39 { 40 siz[x]=1; 41 bool flag=true; 42 for(int i=0;i<G[x].size();i++){ 43 int v=G[x][i]; 44 if(!vist[v]){ 45 vist[v]=true; 46 DFS(x,v);//访问子节点。 47 siz[x]+=siz[v];//回溯计算本节点的siz 48 if(siz[v]>n/2) flag=false;//判断节点x是不是重心。 49 } 50 } 51 if(n-siz[x]>n/2) flag=false;//判断节点x是不是重心。 52 if(flag&&x<point) point=x,father=u;//这里写x<point是因为本题中要求节点编号最小的重心。 53 } 54 55 void init() 56 { 57 memset(vist,false,sizeof(vist)); 58 memset(siz,0,sizeof(siz)); 59 minsum=-1; 60 point=inf; 61 for(int i=0;i<maxn;i++) G[i].clear(); 62 } 63 64 int main() 65 { 66 int t; 67 scanf("%d",&t); 68 while(t--){ 69 scanf("%d",&n); 70 init(); 71 for(int i=1;i<n;i++){ 72 int u,v; 73 scanf("%d%d",&u,&v); 74 G[u].push_back(v); 75 G[v].push_back(u); 76 } 77 vist[1]=1; 78 DFS(-1,1);//任意选取节点作为根,根节点的父亲是-1。 79 for(int i=0;i<G[point].size();i++) 80 if(G[point][i]==father) minsum=max(minsum,n-siz[point]); 81 else minsum=max(minsum,siz[G[point][i]]); 82 printf("%d %d ",point,minsum); 83 } 84 return 0; 85 }
以上是关于POJ 1655.Balancing Act-树的重心(DFS) 模板(vector存图)的主要内容,如果未能解决你的问题,请参考以下文章