POJ 1655 BalanceAct 3107 Godfather (树的重心)(树形DP)
Posted 鲸头鹳
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1655 BalanceAct 3107 Godfather (树的重心)(树形DP)相关的知识,希望对你有一定的参考价值。
树的重心的定义:
树的重心也叫树的质心。找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡。
通常利用树形DP找重心:
BalanceAct: http://poj.org/problem?id=1655
题意:给定一棵树,求树的重心的编号以及重心删除后得到的最大子树的节点个数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\n",ans,size); 63 } 64 return 0; 65 }
Godfather: http://poj.org/problem?id=3107
题意:给定一棵树,求树的所有重心,按照编号从小到大的顺序输出.
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\n",ans[sum]); 60 return 0; 61 }
以上是关于POJ 1655 BalanceAct 3107 Godfather (树的重心)(树形DP)的主要内容,如果未能解决你的问题,请参考以下文章