原题链接:
https://ac.nowcoder.com/acm/problem/15033
题目大意:
树的重心模板题。
解题思路:
树形dp记录每个点下面的节点个数,求出删除一个点时的最大子树大小,比较后得到答案。
代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pi; typedef complex <double> cp; #define debug(a) cout<<#a<<":"<<a<<endl; #define fr freopen("in.txt","r",stdin); #define Fill(x,a) memset(x,a,sizeof(x)) #define cpy(a,b) memcpy(a,b,sizeof(a)) const double PI = acos(-1); const int INF=0x3f3f3f3f; const int N=1e6+7; const int mod=1e9+7; int maxn,minn; int T,n,m,q; struct edges{ int u,next; }edge[N]; int head[N]; int dp[N]; int cnt; int flag; void dfs(int u,int p){ int v,a; a=0; dp[u]=1; for(int i=head[u];i!=0;i=edge[i].next){ v=edge[i].u; if(v==p) continue; dfs(v,u); dp[u]=dp[u]+dp[v]; a=max(dp[v],a); } a=max(a,n-dp[u]); if(a<maxn){ maxn=a; flag=u; } return ; } void init(){ cnt=1; maxn=INF; Fill(head,0); Fill(dp,0); return ; } void add(int u,int v){ edge[cnt].u=v; edge[cnt].next=head[u]; head[u]=cnt++; } int main(){ int u,v; while(cin>>n){ init(); for(int i=1;i<n;i++){ scanf("%d%d",&u,&v); add(u,v); add(v,u); } dfs(1,0); cout<<flag<<" "<<maxn<<endl; } return 0; }