cf#ecr7- E - Ants in Leaves-暴力+贪心

http://codeforces.com/contest/622/problem/E


题意:

给出一棵树,n个节点,根为1,每个叶子上有一只蚂蚁,蚂蚁同时往根爬,每步移动1单位时间,除了节点1,别的节点每一时间只能存在1只蚂蚁。

 求所有蚂蚁到根节点的最短时间。


贪心,考虑每个子树,求子树上所有蚂蚁到根的最长时间。

对每个子树,dfs处理出每个叶子节点的深度,并存起来。

然后遍历每个叶子节点,每个叶子到达根节点的最早时间是,max(自身深度,上一个叶子到达根的时间+1)



答案便是所有叶子中耗时最长的那个。。。



#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int inf=2147483647;
const double pi=acos(-1.0);
double eps=0.000001;
int min(int a,int b)
{return a<b?a:b;}
int max(int a,int b)
{
	return a<b?b:a;
}
  
int n,k;

 vector <vector<int> > sb(500000);
struct node
{
	int x,h;
	node(int a=0,int b=0){ x=a;h=b;}
	bool operator <(const node &b)
	{
		return h<b.h;
	}
};
 vector<node >tmp;
int vis[5+500000];
void dfs(int x,int cur)//给子树标深度,并把叶子放入vector
{
	if (sb[x].size()==1)
	tmp.push_back(node(x,cur ));
	vis[x]=1;
	int i;
	for (i=0;i<sb[x].size();i++)
	{
		int vv=sb[x][i];
		if (vis[vv]) continue;
		dfs(vv,cur+1);
	}

} 
int dis[5+500000];  //记录到根节点的最短时间
 int main()
 {    
	 cin>>n ;
	 int i,x,y,j;
	 for (i=1;i<=n-1;i++)
	 {
		 scanf("%d%d",&x,&y);
		 sb[x].push_back(y);
		 sb[y].push_back(x);
	 } 
 
	int ans=0;
	 for (i=0;i<sb[1].size();i++)
	 {
		 int v=sb[1][i];
		 tmp.clear();
		 vis[1]=1;	
		 dfs(v,1);
		sort(tmp.begin(),tmp.end());	//按深度排序
		for (j=0;j<tmp.size();j++)		//遍历所有叶子
		{
			int vv=tmp[j].x;
			if (!j)
			dis[vv]=tmp[j].h;
			else
				dis[vv]=max(tmp[j].h,dis[tmp[j-1].x]+1);		//该叶子最早到达根的时间是上一个叶子到达时间加1,和,自身深度,的最大值
			ans=max(ans,dis[vv]);
		} 
	 }
	 printf("%d\n",ans);
		  
	return 0;
	
}


你可能感兴趣的:(cf#ecr7- E - Ants in Leaves-暴力+贪心)