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 }

猜你喜欢

转载自www.cnblogs.com/AlphaWA/p/10633054.html