Recently public ancestors ------------ darkness 連 chain

The legendary Dark Chain is known as Dark.
Dark is the product of darkness in the human heart, and the brave men of ancient and modern times have tried to defeat it.
After research, you find that Dark has an undirected graph structure. There are N nodes and two types of edges in the graph. One type of edge is called the main edge, and the other type is called the additional edge.
Dark has N-1 main edges, and there is a path consisting of only main edges between any two nodes in Dark.
In addition, Dark has M additional edges.
Your task is to cut Dark into two disconnected parts.
At first, Dark's additional edges are invincible. You can only choose one main edge to cut off.
Once you cut off a main edge, Dark will enter defense mode, the main edge will become invincible and additional edges can be cut off.
But your ability can only cut an additional edge of Dark.
Now you want to know how many options can defeat Dark.
Note that even if you cut Dark in two steps after cutting the main edge in the first step, you also need to cut an additional edge to defeat Dark.
Input format The
first line contains two integers N and M.
Then N-1 lines, each line includes two integers A and B, indicating that there is a main edge between A and B.
Then M lines give additional edges in the same format.
Output format
Output an integer to indicate the answer.
Data range
N≤100000, M≤200000, data guarantee answer does not exceed 231−1N≤100000, M≤200000, data guarantee answer does not exceed 231−1
Input sample:
4 1
1 2
2 3
1 4
3 4

Sample output:
3

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010, M = 2 * N;
int n, m;
int h[N], e[M], ne[M], idx;
int depth[N], fa[N][17];
int d[N];
int q[N];
int ans;
void add(int a, int b){
 e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
void bfs(){
 memset(depth, 0x3f, sizeof depth);
 depth[0] = 0, depth[1] = 1;
 q[0] = 1;
 int hh = 0, tt = 0; 
 while(hh <= tt){
  int t = q[hh ++];
  for (int i = h[t]; ~i; i = ne[i]){
   int j = e[i];
   if (depth[j] > depth[t] + 1){
    depth[j] = depth[t] + 1;
    q[++ tt] = j;
    fa[j][0] = t;
    for (int k = 1; k <= 16; k ++)
     fa[j][k] = fa[fa[j][k - 1]][k - 1];
   }
  }
 }
}
int lca(int a, int b){
 if (depth[a] <= depth[b])   swap(a, b);
 for (int k = 16; k >= 0; k --)
    if (depth[fa[a][k]] >= depth[b])
      a = fa[a][k];
  if (a == b)   return a;
  for (int k = 16; k >= 0; k --)
     if (fa[a][k] != fa[b][k]){
      a = fa[a][k];
      b = fa[b][k];
  }
   return fa[a][0];
}
int dfs(int u, int father){
 int res = d[u];
 for (int i = h[u]; ~i; i = ne[i]){
  int j = e[i];
  if (j != father){
   int s = dfs(j, u);
   if (s == 0)   ans += m;
   else   if (s == 1)   ans ++;
   res += s;
  }
 }
  return res;
}
int main(){
 scanf("%d%d", &n, &m);
 memset(h, -1, sizeof h);
  for (int i = 0; i < n - 1; i ++){
  int a, b;
  scanf("%d%d", &a, &b);
  add(a, b), add(b, a);
 }
  bfs();
  for (int i = 0; i < m; i ++){
  int a, b;
  scanf("%d%d", &a, &b);
  int p = lca(a, b);
  d[a] ++, d[b] ++, d[p] -= 2;
 }
  dfs(1, -1);
  printf("%d\n", ans);
  return 0;
} 
164 original articles published · Like 112 · Visits 6759

Guess you like

Origin blog.csdn.net/qq_45772483/article/details/105591204