牛客网 2018年全国多校算法寒假训练营练习比赛(第二场) E.小G有一个大树-树的重心
E.小G有一个大树
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
空间限制: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
这个题是树的重心,他们直接找的板子过的,我也没仔细看。。。
代码:
1 #include <cstdio> 2 #include <iostream> 3 #include <fstream> 4 #include <cstring> 5 #include <string> 6 #include <vector> 7 #define OP(s) cout<<#s<<"="<<s<<" "; 8 #define PP(s) cout<<#s<<"="<<s<<endl; 9 using namespace std; 10 int n; 11 vector <int> adj[20010]; 12 int son[20010]; 13 bool vd[20010]; 14 int ans,asize = 1<<29; 15 void DFS(int s){ 16 vd[s] = 1; 17 son[s] = 0; 18 int blance = 0; 19 int size = adj[s].size(); 20 for (int j = 0;j < size;j++){ 21 int u = adj[s][j]; 22 if (vd[u]) continue; 23 DFS(u); 24 son[s] += son[u]+1; 25 blance = max(blance,son[u]+1); 26 } 27 blance = max(blance,n - son[s] - 1); 28 if (blance < asize || blance == asize && s < ans) 29 ans = s,asize = blance; 30 } 31 int main(){ 32 cin>>n; 33 for (int i = 1;i <= n;i++) adj[i].clear(); 34 for (int i = 1;i <= n-1;i++){ 35 int u,v; 36 scanf("%d%d",&u,&v); 37 adj[u].push_back(v); 38 adj[v].push_back(u); 39 } 40 memset(vd,0,sizeof(vd)); 41 asize = 1<<29; 42 DFS(1); 43 cout<<ans<<" "<<asize<<endl; 44 return 0; 45 }