时间限制: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-tot[i],max(tot[k]))
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; } }