题意:给定n个点 m条树上的路径
下面n-1行给出一棵树
目的:
在m条路径中选择尽可能多的路径使得选择的路径互不相交
(相交的意思是一个点在2条及2条以上的路径里出现)
lca。。。
排个序然后暴力保平安
_(:зゝ∠)_
#pragma comment(linker, "/STACK:102400000,102400000")
#include"cstdio"
#include"iostream"
#include"set"
#include"queue"
#include"string.h"
using namespace std;
#define N 100010
struct Edge{
int from, to, nex;
}edge[2*N];
int head[N],edgenum,dis[N],fa[N][20],dep[N]; //fa[i][x] 是i的第2^x个父亲(如果超过范围就是根)
void add(int u,int v){
Edge E={u,v,head[u]};
edge[edgenum] = E;
head[u]=edgenum++;
}
void bfs(int root){
queue<int> q;
fa[root][0]=root;dep[root]=0;dis[root]=0;
q.push(root);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=1;i<20;i++)fa[u][i]=fa[fa[u][i-1]][i-1];
for(int i=head[u]; ~i;i=edge[i].nex){
int v=edge[i].to;if(v==fa[u][0])continue;
dep[v]=dep[u]+1;dis[v]=dis[u]+1;fa[v][0]=u;
q.push(v);
}
}
}
int Lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
for(int i=0;i<20;i++)if((dep[x]-dep[y])&(1<<i))x=fa[x][i];
if(x==y)return x;
for(int i=19;i>=0;i--)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
void init(){memset(head, -1, sizeof head); edgenum = 0;}
int n, m;
struct node{
int l, r, lca;
}q[N];
bool cmp(node a, node b){
return dep[a.lca] > dep[b.lca];
}
int vis[N], tim;
int main(){
int i, j, u, v;
memset(vis, 0, sizeof vis);
tim = 1;
while(~scanf("%d %d",&n,&m)){
init();
tim++;
for(i = 1; i < n; i++)
{
scanf("%d %d",&u,&v);
add(u, v);
add(v, u);
}
bfs(1);
for(i = 1; i <= m; i++)
{
scanf("%d %d",&q[i].l, &q[i].r);
q[i].lca = Lca(q[i].l, q[i].r);
}
sort(q+1, q+1+m, cmp);
int ans = 0;
for(i = 1; i <= m; i++)
{
int lca = q[i].lca;
u = q[i].l, v = q[i].r;
if(vis[lca] == tim)continue;
bool ok = true;
if(u == lca)
{
while(v!=lca){
if(vis[v]==tim){ok = false;break;}
v = fa[v][0];
}
if(ok)
{
ans++;
v = q[i].r;
while(v!=lca){
vis[v]==tim;
v = fa[v][0];
}
vis[lca] = tim;
}
}
else if(v==lca){
while(u!=lca){
if(vis[u]==tim){ok=false;break;}
u = fa[u][0];
}
if(ok)
{
ans++;
u = q[i].l;
while(u!=lca){
vis[u]==tim;
u = fa[u][0];
}
vis[lca] = tim;
}
}
else {
while(v!=lca){
if(vis[v]==tim){ok = false;break;}
v = fa[v][0];
}
if(ok)
while(u!=lca){
if(vis[u]==tim){ok=false;break;}
u = fa[u][0];
}
if(ok)
{
ans++;
u = q[i].l, v = q[i].r;
while(v!=lca){
vis[v]==tim;
v = fa[v][0];
}
while(u!=lca){
vis[u]==tim;
u = fa[u][0];
}
vis[lca] = tim;
}
}
}
cout<<ans<<endl;
}
return 0;
}
/*
9 3
1 2
1 3
2 4
2 5
3 8
3 9
5 6
5 7
1 2
8 9
6 7
9 4
1 2
1 3
2 4
2 5
3 8
3 9
5 6
5 7
1 2
8 9
6 7
2 4
*/