POJ3417(树上差分)
会卡vector。
1 const int maxn = 1e5 + 5; 2 int n, m, Ans; 3 int head[maxn], nxt[maxn * 2], to[maxn * 2], tot; 4 int vis[maxn], f[maxn]; 5 int d[maxn], sum[maxn]; 6 vector<int> q[maxn]; 7 8 inline void Add(int u, int v) { 9 to[++tot] = v, nxt[tot] = head[u], head[u] = tot; 10 } 11 12 inline int getf(int v) { return v == f[v] ? v : f[v] = getf(f[v]); } 13 14 inline void Tarjan(int cur) { 15 vis[cur] = 1; 16 17 for (int j = head[cur]; j; j = nxt[j]) { 18 int i = to[j]; 19 if (vis[i]) continue; 20 Tarjan(i); 21 f[i] = cur; 22 sum[cur] += sum[i]; 23 } 24 25 vis[cur] = 2; 26 27 for (int j = 0; j < q[cur].size(); ++j) { 28 int i = q[cur][j]; 29 if (vis[i] == 2) { 30 int lca = getf(i); 31 d[lca] -= 2; 32 } 33 } 34 35 sum[cur] += d[cur]; 36 if (sum[cur] == 0) Ans += m; 37 else if (sum[cur] == 1) Ans++; 38 } 39 40 int main() { 41 read(n), read(m); 42 43 rep(i, 1, n) 44 f[i] = i; 45 46 rep(i, 1, n - 1) { 47 int u, v; 48 read(u), read(v); 49 Add(u, v), Add(v, u); 50 } 51 52 rep(i, 1, m) { 53 int u, v; 54 read(u), read(v); 55 d[u]++, d[v]++; 56 57 q[u].push_back(v); 58 if (u != v) q[v].push_back(u); 59 } 60 61 Tarjan(1); 62 63 writeln(Ans - m);//1上面没有边,多算了m 64 65 return 0; 66 }