You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
2.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 10, M = N << 1;
int n, k;
//链式前向星
int e[M], h[N], idx, w[M], ne[M];
void add(int a, int b, int c = 0) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
//树上差分模板题【点权】
int depth[N], f[N][25];
int dlt[N];
// 倍增2^k,计算k的办法
// T = log(n) / log(2) + 1;
const int T = 22;
//倍增求 a,b的最近公共祖先
void bfs(int root) {
queue<int> q;
q.push(root);
depth[root] = 1;
while (q.size()) {
int u = q.front();
q.pop();
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (depth[j]) continue;
depth[j] = depth[u] + 1;
f[j][0] = u;
for (int k = 1; k <= T; k++) f[j][k] = f[f[j][k - 1]][k - 1];
q.push(j);
}
}
}
int lca(int a, int b) {
if (depth[a] < depth[b]) swap(a, b);
for (int k = T; k >= 0; k--)
if (depth[f[a][k]] >= depth[b])
a = f[a][k];
if (a == b) return a;
for (int k = T; k >= 0; k--)
if (f[a][k] != f[b][k])
a = f[a][k], b = f[b][k];
return f[a][0];
}
//前缀和
void dfs(int u, int fa) {
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (j == fa) continue;
dfs(j, u);
//遍历完j后dlt[j]已经被填充好可以合并计算dlt[u]了
dlt[u] += dlt[j];
}
}
int main() {
memset(h, -1, sizeof h);
scanf("%d %d", &n, &k);
for (int i = 1; i < n; i++) { // n-1条边
int a, b;
scanf("%d %d", &a, &b);
add(a, b), add(b, a);
}
//预处理出lca需要的depth数组+f数组(倍增位置数组)
bfs(1);
// k条运输牛奶的路线
for (int i = 1; i <= k; i++) {
int a, b;
scanf("%d %d ", &a, &b);
int lc = lca(a, b);
//点差分
dlt[a]++;
dlt[b]++;
//提前就把1减出去了
dlt[lc]--;
dlt[f[lc][0]]--;
}
//利用前缀和合并差分,此时dlt数组的含义已经不是差分了而是结果数组了
dfs(1, 0);
int res = 0; //找出结果数组中的最大值即是答案
for (int i = 1; i <= n; i++) res = max(res, dlt[i]);
printf("%d\n", res);
return 0;
}