朴素版LCA就能过。。标程是树上查分,但数据很水。
标记每一条树边被虚边覆盖的次数,只有一次或零次时,砍此边才能满足,一次时只有一种,零次时有m种。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 100000
using namespace std;
int n,m,adj[N+5],ans=0,e=0;
int f[N+5],dep[N+5],a[N*2+5],bian[N+5];
struct node
{
int v,next;
} lu[N*2+20];
void add(int u,int v)
{
lu[++e].v=v;lu[e].next=adj[u];adj[u]=e;
}
int read()
{
int sum=0;char x=getchar();
while(x<'0'||x>'9')x=getchar();
while(x>='0'&&x<='9')sum=sum*10+x-'0',x=getchar();
return sum;
}
void dfs(int x,int fa)
{
f[x]=fa;
for(int i=adj[x];i;i=lu[i].next)
{
int to=lu[i].v;
if(to!=f[x])
{
bian[to]=i;
dep[to]=dep[x]+1;
dfs(to,x);
}
}
}
void jia(int x,int y)
{
while(x!=y)
{
if(dep[x]<dep[y])swap(x,y);
a[bian[x]]++;
x=f[x];
}
}
void zhao(int x)
{
for(int i=adj[x];i;i=lu[i].next)
if(lu[i].v!=f[x])
{
if(!a[i])
ans+=m;
else
if(a[i]==1)
ans+=1;
zhao(lu[i].v);
}
}
int yjn()
{
freopen("yam.in","r",stdin);
freopen("yam.out","w",stdout);
n=read();m=read();
int x,y;
for(int i=1;i<n;i++)
{
x=read();y=read();
add(x,y);
add(y,x);
}
dfs(1,0);
for(int i=1;i<=m;i++)
{
x=read();y=read();
jia(x,y);
}
zhao(1);
printf("%d",ans);
//for(int i=1;i<=n;i++)
// cout<<bian[i]<<" "<<a[bian[i]]<<endl;
}
int qty=yjn();
int main(){;}