AcWing 352. 闇の連鎖 -- tarjan算法
原题链接
困难
作者:
东方晓
,
2021-03-28 21:57:19
,
所有人可见
,
阅读 449
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 100010, M = 200010;
int n, m;
int h[N], e[M], ne[M], tot;
int p[N], mk[N], d[N], ans;
vector<int> query[M];
void add(int a, int b) {
e[++ tot] = b; ne[tot] = h[a]; h[a] = tot;
}
int find(int x) {
return x == p[x] ? x: p[x] = find(p[x]);
}
void tarjan(int x) {
mk[x] = 1;
for(int i = h[x]; i; i = ne[i]) {
int y = e[i];
if(mk[y]) continue;
tarjan(y);
p[y] = x;
}
mk[x] = 2;
for(int y : query[x])
if(mk[y] == 2) {
d[x] ++; d[y] ++; d[find(y)] -= 2;
}
}
int dfs(int x, int fa) {
int res = d[x];
for(int i = h[x]; i; i = ne[i]) {
int y = e[i];
if(y == fa) continue;
int s = dfs(y, x);
if(s == 0) ans += m;
else if(s == 1) ans ++;
res += s;
}
return res;
}
int main() {
cin >> n >> m;
for(int i = 0; i < n - 1; i ++) {
int a, b;
scanf("%d%d", &a, &b);
add(a, b), add(b, a);
}
for(int i = 1; i <= n; i ++) p[i] = i;
for(int i = 0; i < m; i ++) {
int a, b;
scanf("%d%d", &a, &b);
query[a].push_back(b);
query[b].push_back(a);
}
tarjan(1);
dfs(1, -1);
printf("%d\n", ans);
return 0;
}
这里为什么不能直接在读入m条树外边的时候
d[a] ++, d[b] ++
呢, 要离线的时候再加是为什么,读入加是错的