题目描述
体育场突然着火了,现场需要紧急疏散,但是过道真的是太窄了,同时只能容许一个人通过。现在知道了体育场的所有座位分布,座位分布图是一棵树,已知每个座位上都坐了一个人,安全出口在树的根部,也就是1号结点的位置上。其他节点上的人每秒都能向树根部前进一个结点,但是除了安全出口以外,没有任何一个结点可以同时容纳两个及以上的人,这就需要一种策略,来使得人群尽快疏散,问在采取最优策略的情况下,体育场最快可以在多长时间内疏散完成。
输入描述
第一行包含一个正整数n,即树的结点数量(1<=n<=100000)。 接下来有n-1行,每行有两个正整数x,y,表示在x和y结点之间存在一条边。(1<=x,y<=n)。
输出描述
输出仅包含一个正整数,表示所需要的最短时间。
解题思路
按照题目的设定,每一次每一棵子树都会有一个节点通过出口成功离开,但是对于每一棵子树来说,一次只能离开一个,那么无论采取什么样的措施,如果一棵子树有M个节点,则需要M个单位时间,所以对于整棵树来说,总共花费的时间就是最大的子树的节点数,因此这道题本质上就是求最大子树。
由于这里每一行输入的是一条边的两个端点,可以将其作为无向图保存。
代码实现
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int> > data(100010,vector<int>());
int getTreeSum(int i,int pre){
int len=data[i].size();
int sum=0;
for(int j=0;j<len;j++)
if(data[i][j]!=pre)
sum+=getTreeSum(data[i][j],i);
sum++;
return sum;
}
int MaxSubTree(){
int len=data[1].size();
int max=0;
int sum;
for(int i=0;i<len;i++){
sum=getTreeSum(data[1][i],1);
if(max<sum)
max=sum;
}
return max;
}
int main(){
int n,x,y;
cin>>n;
for(int i=1;i<n;i++){
cin>>x>>y;
data[x].push_back(y);
data[y].push_back(x);
}
int sum=MaxSubTree();
cout<<sum<<endl;
return 0;
}