题意:
给出一颗根节点为1的树,树的每个叶子结点都有一只蚂蚁,现在所有蚂蚁要到根节点1去问最少时间多少, 每秒钟蚂蚁移动一个结点,每个结点除根节点外只能有一个蚂蚁(可以同时有多个蚂蚁到达根节点)。 思路:
这个题的话,看到了是树.还是个E题,一般会去想树形dp,可是仔细一想的话其实贪心是可以解决的.由于可以从一号点所有的子孩子同时到达1(不阻塞),那么我们只需要找到1号点所有的孩子所分别构成的子树中,到根节点最长的时间是多少,最后在维护这个最大值就可以啦.我们对于每一个子树求出其叶子节点的深度,然后按照从小到大排序,对于当前的叶子节点到达根节点的时间,与前一个+1取最大值.(加1是因为当两个叶子到根节点的时间相同,即深度相同时需要阻塞一秒钟),然后维护整体最大值就可以了。num[i]=max(num[i-1]+1,num[i]);
#include<bits/stdc++.h> #define Ri(a) scanf("%d", &a) #define Rl(a) scanf("%lld", &a) #define Rf(a) scanf("%lf", &a) #define Rs(a) scanf("%s", a) #define Pi(a) printf("%d\n", (a)) #define Pf(a) printf("%lf\n", (a)) #define Pl(a) printf("%lld\n", (a)) #define Ps(a) printf("%s\n", (a)) #define W(a) while(a--) #define CLR(a, b) memset(a, (b), sizeof(a)) #define MOD 1000000007 #define inf 0x3f3f3f3f #define pb push_back using namespace std; typedef long long ll; const int maxn=1e5+10; int n; int num[5*maxn]; vector<int>vt[5*maxn]; int k; int book[5*maxn]; void dfs(int x,int deep) { book[x]=1; if(vt[x].size()==1) { num[k++]=deep; //printf("%d ",x); //Pi(deep); return ; } for(int i=0;i<vt[x].size();i++) { int v=vt[x][i]; if(!book[v]) { dfs(v,deep+1); } } return ; } int main() { int x,y; Ri(n); for(int i=1;i<n;i++) { Ri(x),Ri(y); vt[x].pb(y); vt[y].pb(x); } //puts(""); int ans=0; CLR(book,0); CLR(num,0); book[1]=1; for(int i=0;i<vt[1].size();i++) { k=0; int v=vt[1][i]; //cout<<v<<' '<<endl; dfs(v,1); sort(num,num+k); for(int j=1;j<k;j++) { num[j]=max(num[j-1]+1,num[j]); } ans=max(ans,num[k-1]); } Pi(ans); return 0; }