题意:一棵树根节点是1,每个叶子节点有一只蚂蚁,每单位时间可以爬到当前节点的父亲,除了根节点某个节点不能出现多于两只蚂蚁。求所有蚂蚁到达根节点的最少时间。
对于因为根节点的特殊性可以把根节点分开来考虑,对于根节点的每个子树,只需要知道某个子树蚂蚁爬完的最大值。而对于不能在同一个节点存在两只蚂蚁的子树,可以先求出所有的蚂蚁爬到这个子树根节点的时间,然后相同的时间必须要加一,他们必须错开到达这个子树根节点的时间。
#include <cstdio>
#include <cmath>
#include <iostream>
#include <vector>
#include <cstring>
#include <bits/stdc++.h>
using namespace std;
#define maxn 511111
#define maxm 1111111
struct node {
int u, v, next;
}edge[maxm];
vector <int> a;
int head[maxn], cnt;
int n;
void add_edge (int u, int v) {
edge[cnt].u = u; edge[cnt].v = v; edge[cnt].next = head[u]; head[u] = cnt++;
return ;
}
void dfs (int u, int deep, int father) {
int son = 0;
for (int i = head[u]; i != -1; i = edge[i].next) {
int v = edge[i].v;
if (v == father)
continue;
dfs (v, deep+1, u);
son++;
}
if (!son)
a.push_back (deep);
}
int main () {
scanf ("%d", &n);
memset (head, -1, sizeof head);
cnt = 0;
int u, v;
for (int i = 0; i < n-1; i++) {
scanf ("%d%d", &u, &v);
add_edge (u, v);
add_edge (v, u);
}
int ans = 0;
for (int i = head[1]; i != -1; i = edge[i].next) {
a.clear ();
int v = edge[i].v;
dfs (v, 1, 1);
sort (a.begin (), a.end ());
//for (int i = 0; i < a.size (); i++) cout << a[i] << " "; cout << endl;
int l = a.size ();
for (int i = 1; i < l; i++) {
a[i] = max (a[i-1]+1, a[i]);
}
ans = max (ans, a[l-1]);
}
cout << ans << endl;
return 0;
}