来源:牛客网
:
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
小G想要把自己家院子里的橘子树搬到家门口(QAQ。。就当小G是大力水手吧)
可是小G是个平衡性灰常灰常差的人,他想找到一个这个橘子树的平衡点。 怎么描述这棵树呢。。。就把它看成由一个个节点构成的树吧。结点数就
代表树重。
输入描述:
多组数据输入输出, 第一行包含一个整数n(3<=n<=1000)代表树的结点的个数 以下n-1行描述(1-n)节点间的连接关系。 输出描述:
输出两个个整数 x,num 分别代表树的平衡点,和删除平衡点后最大子树的结点数(如果结点数相同输出编号小的)。
示例1
输入
复制
3
1 2
1 3
输出
复制
1 1
题解:
树型dp入门
状态转移方程:dp[i]=max(n-dp[i],max(dp[k])),k是i的儿子
dp[x]:表示以x为根的树的节点数
在dfs过程中把状态转移方程带进去
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1010;
vector<int>edge[maxn];
int num,ans;
int dp[maxn];
int n;
void dfs(int u,int fa)
{dp[u]=1;int maxx=0;for(int i=0;i<edge[u].size();i++){int v=edge[u][i];if(v==fa)continue;dfs(v,u);dp[u]+=dp[v];//v是u的子树 maxx=max(dp[v],maxx);}maxx=max(maxx,n-dp[u]);//判断是这个子树重,还是另一个 // dp[i]=max(n-tot[i],max(tot[k])) 树形dp if(maxx<num)//删除平衡点后最大子树的结点数{num=maxx;ans=u; }else if(maxx==num){if(ans>u)ans=u;//如果结点数相同,我们要编号更小的 }
}
int main()
{while(cin>>n){num=ans=0x7f;for(int i=1;i<=n;i++){edge[i].clear();dp[i]=0;}for(int i=1;i<n;i++){int u,v;cin>>u>>v;edge[u].push_back(v);edge[v].push_back(u);}dfs(1,0);cout<<ans<<" "<<num<<endl;}
}