1、http://poj.org/problem?id=1655
2、题目大意:
一棵树有n个点,每个点都有一个平衡值,就是该点的子树中结点数最大值,现在要删除这样一个点,他的平衡值最小,本题只有一种方式,不用考虑是否有重复值,只需要输出最小的那个点及他的平衡值即可
dp[i]表示i点的平衡值
dp[i]=max(max(cnt[v]),n-cnt[u])
3、AC代码:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define N 20005 #define INF 20005 int v[N*2],next[N*2],head[N*2]; int tot; int cnt[N]; int ans,res,n; int dp[N]; void add_edge(int a,int b) { v[tot]=b; next[tot]=head[a]; head[a]=tot++; } void dfs(int u,int fa) { cnt[u]=1; for(int i=head[u];i!=-1;i=next[i]) { int vv=v[i]; if(vv!=fa) { dfs(vv,u); cnt[u]+=cnt[vv]; ans=max(ans,cnt[vv]); } } dp[u]=max(ans,n-cnt[u]); res=min(dp[u],res); } int main() { int t,a,b; scanf("%d",&t); while(t--) { scanf("%d",&n); tot=0; memset(head,-1,sizeof(head)); memset(cnt,0,sizeof(cnt)); memset(dp,0,sizeof(dp)); for(int i=1;i<n;i++) { scanf("%d%d",&a,&b); add_edge(a,b); add_edge(b,a); } ans=-INF; res=INF; dfs(1,0); for(int i=1;i<=n;i++) { if(dp[i]==res) { printf("%d %d\n",i,dp[i]); break; } } } return 0; } /* 8 2 6 1 2 1 4 4 5 3 7 3 1 1 8 */