The meaning of problems: a communication undirected graph nodes n, n-1 bar side of the tree, m article non-tree edges. If the edge by first cut a tree, and then delete a non-tree edge to operate
This map is divided into two parts disconnected, asked how many kinds of programs.
Covering the whole good section using LCA, dfs prefix for seeking and
It should be noted that the number of cover before they can choose when to Oh 1!
Covering number is 0, which means you can directly open
Finally, attach one of my wife
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #define maxn 110000 using namespace std; typedef long long ll; int dp[maxn][33]; int dep[maxn]; long long cnt[maxn];//差分数组 int head[450100]; struct Node { int to; int next; }G[450100]; int cnn = 1; void insert(int be, int en) { G[cnn].to = en; G[cnn].next = head[be]; head[be] = cnn;;//头插法 cnn++; } void dfs(int u, int par) { dep[u] = dep[par] + 1; for (int i = 0; i <= 21; i++) { dp[u][i + 1] = dp[dp[u][i]][i]; } for (int i = head[u]; i; i = G[i].next) { int p = G[i].to; if (p == par) continue; dp[p][0] = u; dfs(p, u); } return; } int LCA(int x, int y) { if (dep[x] < dep[y]) swap(x, y);//x在下面 for (int i = 20; i >= 0; i--) { if (dep[dp[x][i]] >= dep[y]) x = dp[x][i]; if (x == y) return x; } for (int i = 20; i >= 0; i--) { if (dp[x][i] != dp[y][i]) { x = dp[x][i]; y = dp[y][i]; } } return dp[x][0]; } int n, m; int find(int x,int par) { for (int i = head[x]; i; i = G[i].next) { int p = G[i].to; if (p == par) continue; find(p, x); cnt[x] += cnt[p]; } return 0; } int main() { scanf("%d %d", &n, &m); int be, en; for (int i = 0; i < n - 1; i++) { scanf("%d %d", &be, &en); insert(be, en); insert(en, be); } dp[1][0] = 1; dfs(1, 0); for(int i=0;i<m;i++) { scanf("%d %d", &be, &en); int p = LCA(be, en); cnt[p] -= 2; cnt[be]++; cnt[en]++; } find(1, 0); ll ans = 0; for (int i = 2; i <= n; i++) { if (cnt[i] == 0) ans += m;//乘法原理 else if (cnt[i] == 1) ans++; } printf("%lld\n", ans); return 0; }