紧急疏散(最大子树)

题目描述

  体育场突然着火了,现场需要紧急疏散,但是过道真的是太窄了,同时只能容许一个人通过。现在知道了体育场的所有座位分布,座位分布图是一棵树,已知每个座位上都坐了一个人,安全出口在树的根部,也就是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;
}

发布了16 篇原创文章 · 获赞 0 · 访问量 335

猜你喜欢

转载自blog.csdn.net/qq_41922018/article/details/104382149