POJ-1655 Balancing Act
题目大意:一棵n个节点的树,找出最大子树最小的节点。
题目分析:过程类似求重心。
代码如下:
# include<iostream> # include<cstdio> # include<cstring> # include<vector> # include<queue> # include<list> # include<set> # include<map> # include<string> # include<cmath> # include<cstdlib> # include<algorithm> using namespace std; # define LL long long const int N=1005; const int INF=1000000000; int n,dp[N*20]; int size[N*20]; vector<int>e[N*20]; void init() { scanf("%d",&n); for(int i=1;i<=n;++i) e[i].clear(); int a,b; for(int i=1;i<n;++i){ scanf("%d%d",&a,&b); e[a].push_back(b); e[b].push_back(a); } } void dfs(int u,int fa) { size[u]=1; for(int i=0;i<e[u].size();++i){ int v=e[u][i]; if(v==fa) continue; dfs(v,u); size[u]+=size[v]; } } void dfs1(int u,int fa) { dp[u]=n-size[u]; for(int i=0;i<e[u].size();++i){ int v=e[u][i]; if(v==fa) continue; dp[u]=max(dp[u],size[v]); dfs1(v,u); } } void solve() { dfs(1,-1); dfs1(1,-1); dp[0]=INF; int root=0; for(int i=1;i<=n;++i) if(dp[i]<dp[root]) root=i; printf("%d %d\n",root,dp[root]); } int main() { int T; scanf("%d",&T); while(T--) { init(); solve(); } return 0; }