居然贪心。
先求LCA,都保存好,然后按lca的深度排序,一个个判断,可以取的话将子树都标记了,再看下一个。
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
using namespace std;
struct node
{
int l,r,top,c;
} p[111111];
vector<int>g[111111];
vector<int>d[111111];
bool vis[111111];
bool vv[111111];
int r[111111];
int f[111111];
int c[111111];
int m,n,ans,num;
void init()
{
num=0;
memset(vis,0,sizeof(vis));
memset(r,0,sizeof(r));
memset(vv,0,sizeof(vv));
for(int i=1; i<=n; i++){g[i].clear();d[i].clear();f[i]=i;}
}
int find(int x)
{
if(f[x]==x)return x;
f[x]=find(f[x]);
return f[x];
}
void mark(int u)
{
vv[u]=1;
int size=g[u].size();
for(int i=0; i<size; i++)
{
int v=g[u][i];
if(c[u]>c[v])continue;
if(vv[v]==1)continue;
mark(v);
}
}
void dfs(int u)
{
vis[u]=1;
int size=d[u].size();
for(int i=0; i<size; i++)
{
int v=d[u][i];
if(vis[v])
{
int fa=find(v);
p[num].l=u;p[num].r=v;p[num].top=fa;p[num].c=c[fa];
num++;
}
}
size=g[u].size();
for(int i=0; i<size; i++)
{
int v=g[u][i];
if(v==r[u])continue;
c[v]=c[u]+1;r[v]=u;dfs(v);
}
f[u]=r[u];
}
bool cmp(node x,node y)
{
return x.c>y.c;
}
void solve()
{
sort(p,p+num,cmp);
for(int i=0; i<num; i++)
{
if(!vv[p[i].l]&&!vv[p[i].r])
{
ans++;mark(p[i].top);
}
}
}
int main()
{
int u,v;
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
for(int i=1; i<n; i++)
{
scanf("%d%d",&u,&v);
g[u].push_back(v);g[v].push_back(u);
}
for(int i=0; i<m; i++)
{
scanf("%d%d",&u,&v);
d[u].push_back(v);d[v].push_back(u);
}
ans=0;
c[1]=1;
r[1]=1;
dfs(1);
solve();
printf("%d\n",ans);
}
return 0;
}