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