Pagini recente » Cod sursa (job #3277050) | Cod sursa (job #334282) | Cod sursa (job #2187969) | Istoria paginii utilizator/mocke | Cod sursa (job #1758913)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("ct.in");
ofstream fout("ct.out");
const int NMAX = 1e5 + 5;
const int LMAX = 16;
int n, m;
vector<int> g[NMAX];
int str[LMAX][NMAX];
int h[NMAX];
int lgg[NMAX];
int taken[NMAX], cnt;
vector<int> ancestors;
int sons[NMAX][2];
//lanturi in arbore => lca, cauta ce mai simpla alegere pe care o poti face
void read() {
fin >> n >> m;
for(int i = 1; i < n; ++i) {
int x, y; fin >> x >> y;
g[x].push_back(y);
g[y].push_back(x);
}
}
void dfs(int node, int fath) {
h[node] = h[fath] + 1;
str[0][node] = fath;
for(int x : g[node])
if(x != fath)
dfs(x, node);
}
int lca(int x, int y) {
if(h[x] > h[y])
swap(x, y);
int urc = h[y] - h[x];
while(urc > 0) {
int lg = lgg[urc];
y = str[lg][y];
urc = h[y] - h[x];
}
if(x == y) return x;
//h[x] = h[y]
for(int i = 13; i >= 0 ;--i) {
if(str[i][x] && str[i][y] && str[i][x] != str[i][y]) {
x = str[i][x];
y = str[i][y];
}
}
return str[0][x];
}
struct Cmp {
bool operator()(const int x, const int y) {
return h[x] > h[y];
}
} cmph;
void dfs2(int node, int fath) {
taken[node] = 1;
for(int x : g[node])
if(x != fath && taken[x] == 0)
dfs2(x, node);
}
void solve() {
dfs(1, 0);
for(int i = 1; i < LMAX; ++i)
for(int j = 1; j <= n; ++j)
str[i][j] = str[i - 1][ str[i - 1][j] ];
lgg[1] = 0;
for(int i = 2; i <= n; ++i)
lgg[i] = lgg[i / 2] + 1;
while(m--) {
int x, y;
fin >> x >> y;
int lc = lca(x, y);
sons[lc][0] = x;
sons[lc][1] = y;
ancestors.push_back(lc);
}
sort(ancestors.begin(), ancestors.end(), cmph);
for(int x : ancestors)
if(taken[ sons[x][0] ] == 0 && taken[ sons[x][1] ] == 0)
dfs2(x, str[0][x]), cnt++;
fout << cnt << '\n';
}
void curata() {
for(int i = 1; i <= n ; ++i)
g[i].clear(), taken[i] = 0;
cnt = 0;
ancestors.clear();
}
int main() {
int t;
fin >> t;
while(t--) {
read();
solve();
curata();
}
return 0;
}