题目链接:
https://ac.nowcoder.com/acm/contest/884/A
题意:
给一个树形结构,有K个点上有人,确定在哪个点集合耗时最少
题解:
树的直径水题,答案为树的直径/2(向上取整)。
跑两遍DFS,第一次任选一个有人的起点出发,选出离起点最远的点p,再以p为起点,选出离p最远的点q,pq之间的路径即为树的直径。
代码:
const int MAX = 1e5 + 10;
int N, K, S;
int dis[MAX], f[MAX];
struct edge {
int nxt, to;
}e[MAX << 1];
int head[MAX], tot;
void add(int u, int v) {
e[++tot].to = v;
e[tot].nxt = head[u];
head[u] = tot;
}
void dfs(int u, int fa) {
for (int i = head[u]; i; i = e[i].nxt)
if (e[i].to != fa) {
dis[e[i].to] = dis[u] + 1;
dfs(e[i].to, u);
}
}
int solve() {
dfs(S, 0);
int maxx = 0;
for (int i = 1; i <= N; i++)
if (f[i] && dis[i] > maxx) {
maxx = dis[i];
S = i;
}
dis[S] = 0;
dfs(S, 0);
for (int i = 1; i <= N; i++)
if (f[i] && dis[i] > maxx)
maxx = dis[i];
return maxx;
}
int main() {
ios::sync_with_stdio(0);
tot = 0;
cin >> N >> K;
for (int i = 1; i < N; i++) {
int u, v;
cin >> u >> v;
add(u, v);
add(v, u);
}
for (int i = 1; i <= K; i++) {
int n;
cin >> n;
f[n] = 1;
S = n;
}
cout << (solve() + 1) / 2 << endl;
return 0;
}