POJ 1655 BalanceAct 3107 Godfather (树的重心)(树形DP)

 

树的重心的定义:

的重心也叫树的质心。找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡。
通常利用树形DP找重心:
题意:给定一棵树,求树的重心的编号以及重心删除后得到的最大子树的节点个数size,如果size相同就选取编号最小的
清空的时候记得要清干净.....
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 const int maxn=20010;
 8 const int maxx=1<<30;
 9 int t,n;
10 int f[maxn]={};
11 int vis[maxn]={};
12 struct nod{
13     int y;
14     int next;
15 }e[2*maxn]={};
16 int head[maxn]={},tot=0;
17 int ans,size=0;
18 void init(int x,int y){
19     e[++tot].y=y;
20     e[tot].next=head[x];
21     head[x]=tot;
22 }
23 void dfs(int x){
24     int y;
25     vis[x]=1;
26     f[x]=0;
27     int tmp=0;
28     for(int i=head[x];i;i=e[i].next){
29         y=e[i].y;
30         if(!vis[y]){
31             dfs(y);
32             f[x]+=f[y]+1;
33             tmp=max(tmp,f[y]+1);
34         }
35     }tmp=max(tmp,n-f[x]-1);
36     if(tmp<size||(tmp==size&&x<ans)){
37         size=tmp;
38         ans=x;
39     }
40 }
41 void yu(){
42     size=maxx;
43     ans=maxx;
44     tot=0;
45     memset(f,0,sizeof(f));
46     memset(vis,0,sizeof(vis));
47     memset(head,0,sizeof(head));
48     memset(e,0,sizeof(e));
49 }
50 int main(){
51     scanf("%d",&t);
52     while(t-->0){
53         yu();
54         scanf("%d",&n);
55         int x,y;
56         for(int i=1;i<n;i++){
57             scanf("%d%d",&x,&y);
58             init(x,y);
59             init(y,x);
60         }
61         dfs(1);
62         printf("%d %d
",ans,size);
63     }
64     return 0;
65 }
View Code
题意:给定一棵树,求树的所有重心,按照编号从小到大的顺序输出.
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 const int maxn=50010;
 8 const int maxx=1<<30;
 9 int t,n;
10 int f[maxn]={};
11 int vis[maxn]={};
12 struct nod{
13     int y;
14     int next;
15 }e[2*maxn]={};
16 int head[maxn]={},tot=0;
17 int ans[maxn]={},size=0,sum=0;
18 void init(int x,int y){
19     e[++tot].y=y;
20     e[tot].next=head[x];
21     head[x]=tot;
22 }
23 void dfs(int x){
24     int y;
25     vis[x]=1;
26     int tmp=0;
27     for(int i=head[x];i;i=e[i].next){
28         y=e[i].y;
29         if(!vis[y]){
30             dfs(y);
31             f[x]+=f[y]+1;
32             tmp=max(f[y]+1,tmp);
33         }
34     }
35     tmp=max(tmp,n-f[x]-1);
36     if(tmp<size){
37         size=tmp;
38         sum=0;
39         ans[++sum]=x;
40     }
41     else if(tmp==size){
42         ans[++sum]=x;
43     }
44 }
45 int main(){
46     size=maxx;
47     scanf("%d",&n);
48     int x,y;
49     for(int i=1;i<n;i++){
50         scanf("%d%d",&x,&y);
51         init(x,y);
52         init(y,x);
53     }
54     dfs(1);
55     sort(ans+1,ans+1+sum);
56     for(int i=1;i<sum;i++){
57         printf("%d ",ans[i]);
58     }
59     printf("%d
",ans[sum]);
60     return 0;
61 }
View Code
原文地址:https://www.cnblogs.com/137shoebills/p/7783888.html