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;
}