题目链接:点击打开链接
题意:给出一棵n个结点的树, 每个叶子结点上有一只蚂蚁, 每秒每只蚂蚁可以向相邻结点走一步, 同一时刻同一结点上只能有最多一只蚂蚁(根结点除外),根结点为1, 求所有蚂蚁都移动到1上的最小花费时间。
思路:很容易想到,采取贪心的思路就行了, 那么只要不断向上走就行了, 因为根结点比较特殊, 我们只考虑它的子树, 对于它的每一棵子树, 先dfs处理出所有结点的深度,然后对深度排序, 那么计算每个叶子结点到达根结点的时间。 假设第i个蚂蚁到达根结点的时间等于a[i],那么显然a[i] = max(a[i-1]+1, d[i]),等于上一个蚂蚁的时间+1和它所在深度的最大值。
细节参见代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int mod = 1000000000 + 7;
const int INF = 1000000000;
const int maxn = 500000 + 10;
int T,n,m,a[maxn];
vector<int> g[maxn];
vector<int> d;
void dfs(int root,int fa, int cnt) {
int len = g[root].size();
if(len == 1) d.push_back(cnt);
for(int i=0;i<len;i++) {
int v = g[root][i];
if(v != fa) {
dfs(v, root, cnt+1);
}
}
}
int u, v;
int main() {
scanf("%d",&n);
for(int i=1;i<=n;i++) g[i].clear();
for(int i=1;i<n;i++) {
scanf("%d%d",&u,&v);
g[v].push_back(u);
g[u].push_back(v);
}
int len = g[1].size(), ans = 0;
for(int i=0;i<len;i++) {
int root = g[1][i];
d.clear();
dfs(root, 1, 0);
sort(d.begin(), d.end());
int l = d.size();
for(int j=1;j<l;j++) {
d[j] = max(d[j], d[j-1]+1);
}
ans = max(ans, d.back());
}
printf("%d\n",ans+1);
return 0;
}