朴素版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(){;}