POJ-1655 Balancing Act

时间:2023-03-09 07:38:06
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;
}