任選一點爲根後,貪心優先填所有點對中LCA大的點。那麼以LCA爲根的子樹的所有點都爲不能再選的點
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define ls rt<<1
#define rs rt<<1|1
#define fi first
#define se second
#define pb push_back
using namespace std;
typedef long long ll;
typedef vector<int> VI;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const ll inf = 0x3f3f3f3f;
const int mod = 20200501;
const int maxn = 2e5 + 6;
const int N = 5e3 + 4;
const double eps = 1e-6;
ll qpow(ll x,ll y){ll ans=1;x%=mod; while(y){ if(y&1) ans=ans*x%mod; x=x*x%mod; y>>=1;}return ans;}
int n,m,lgN,vis[maxn],fa[maxn][25],dep[maxn],id[maxn];
VI G[maxn];
void dfs(int u){
dep[u]=dep[fa[u][0]]+1;
for(int i=1;i<=lgN;i++){
fa[u][i]=fa[fa[u][i-1]][i-1];
}
for(int v:G[u]) if(v!=fa[u][0]){
fa[v][0]=u;
dfs(v);
}
}
void dfs1(int u){
vis[u]=1;
for(int v:G[u]) if(!vis[v]&&v!=fa[u][0]){
dfs1(v);
}
}
int LCA(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
for(int i=lgN;i>=0;i--){
if(dep[fa[x][i]]>=dep[y]) x=fa[x][i];
}
if(x==y) return x;
for(int i=lgN;i>=0;i--){
if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
}
return fa[x][0];
}
int a[maxn],b[maxn],c[maxn];
int main(){
while(~scanf("%d%d",&n,&m)){
for(int i=1;i<=n;i++){
G[i].clear();
id[i]=i;
vis[i]=0;
}
lgN=(int)log(n)/log(2)+1;
for(int i=1;i<n;i++){
int u,v;scanf("%d%d",&u,&v);
G[u].pb(v);G[v].pb(u);
}
dfs(1);
for(int i=1;i<=m;i++){
scanf("%d%d",&a[i],&b[i]);
c[i]=LCA(a[i],b[i]);
}
sort(id+1,id+1+m,[](int x,int y){
return dep[c[x]]>dep[c[y]];
});
int ans=0;
for(int i=1;i<=m;i++){
if(vis[a[id[i]]]||vis[b[id[i]]]) continue;
dfs1(c[id[i]]);
ans++;
//cout<<id[i]<<',';
}
printf("%d\n",ans);
}
}