poj 3107 Godfather

来源:互联网 发布:有后台手机导航源码 编辑:程序博客网 时间:2024/05/16 20:16

题目大意:

求一颗树的所有重心;

解题思路:

树的重心的求法我在poj 1655中详细讲过,这里就不说啦,这道题目是要求求出所有的重心,因此题目中会有很多最小的最大子树结点数相同,我们只需要在求最小值的时候处理一下等于号,如果不相等,置空答案数组重新存储,如果相等,则在答案数组中顺次存储;
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define maxn 50010int cnt,head[maxn];bool vis[maxn];int size[maxn],dp[maxn];int n;struct Edge{int to,next;}edge[2*maxn];void init(){cnt=0;memset(head,-1,sizeof(head));memset(vis,0,sizeof(vis));memset(size,0,sizeof(size));memset(dp,0,sizeof(dp));}void addedge(int u,int v){edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;}void dfs(int u){vis[u]=true;size[u]=1;dp[u]=0;for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;if(!vis[v]){dfs(v);size[u]+=size[v];dp[u]=max(dp[u],size[v]);} }dp[u]=max(dp[u],n-size[u]);}void ans(){int t=maxn;int print[maxn];int cot=0;for(int i=1;i<=n;i++){if(dp[i]<t){cot=0;print[cot++]=i;t=dp[i];}else if(dp[i]==t){print[cot++]=i;}}for(int i=0;i<cot;i++)printf("%d ",print[i]);printf("\n");}int main(){while(~scanf("%d",&n)){init();for(int i=0;i<n-1;i++){int a,b;scanf("%d%d",&a,&b);addedge(a,b);addedge(b,a);}dfs(1);ans();}}


0 0
原创粉丝点击