analysis
这是一道好题诶!对于我这种蒟蒻来说是属于比较考思维的一道题
开始看到题一脸懵逼,根本不知道从何下手
看到书上的讲解后才恍然大悟:原来就是个差分嘛!
我们枚举每条非树边(x,y),把x到y路径上所有边的边权+1,对于每条树边,如果边权为0,则切断它之后原图已经不联通,第二条边随便切一条,共m种方案。如果边权为1,则第二步必须切断对应的那条边,方案数1,如果边权大于2则没有方案。
但是怎么维护呢?差分!怎么差分呢?LCA!
这就是这个题的目的,将LCA问题放在差分中来考
若是有人在我思考这个题的时候突然告诉我说:这个题用差分!十有八九我都能够想得出来
不过既然没有人告诉我,我就自己告诉自己
#include<bits/stdc++.h>
using namespace std;
#define loop(i,start,end) for(register int i=start;i<=end;++i)
#define anti_loop(i,start,end) for(register int i=start;i>=end;--i)
#define clean(arry,num) memset(arry,num,sizeof(arry))
#define ll long long
template<typename T>void read(T &x){
x=0;char r=getchar();T neg=1;
while(r>'9'||r<'0'){if(r=='-')neg=-1;r=getchar();}
while(r>='0'&&r<='9'){x=(x<<1)+(x<<3)+r-'0';r=getchar();}
x*=neg;
}
int n,m,cnt=0;
const int maxn=1e5+10,maxm=2e5+10;
struct node{int e;int nxt;}edge[maxn<<2];
int head[maxn];
inline void addl(int u,int v){
edge[cnt].e=v;
edge[cnt].nxt=head[u];
head[u]=cnt++;
}
int siz[maxn];
int son[maxn];
int dep[maxn];
int fa[maxn];
void dfs1(int u,int f){
dep[u]=dep[f]+1;
fa[u]=f;
siz[u]=1;
son[u]=0;
for(int i=head[u];i!=-1;i=edge[i].nxt){
int v=edge[i].e;
if(v==f)
continue;
dfs1(v,u);
siz[u]+=siz[v];
son[u]=((siz[son[u]]<siz[v])?v:son[u]);
}
}
int top[maxn];
void dfs2(int u){
if(son[u]){
top[son[u]]=top[u];
dfs2(son[u]);
}
for(int i=head[u];i!=-1;i=edge[i].nxt){
int v=edge[i].e;
if(!top[v]){
top[v]=v;
dfs2(v);
}
}
}
inline int LCA(int u,int v){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]){
swap(u,v);
}
u=fa[top[u]];
}
return ((dep[u]<dep[v])?u:v);
}
int W[maxn];
void updateW(int pos,int f){
for(int i=head[pos];i!=-1;i=edge[i].nxt){
int v=edge[i].e;
if(v==f)
continue;
updateW(v,pos);
W[pos]+=W[v];
}
}
void debug(){
loop(i,1,n){
printf("%d\n",W[i]);
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("datain.txt","r",stdin);
#endif // ONLINE_JUDGE
read(n),read(m);
clean(head,-1);
clean(W,0);
loop(i,1,n-1){
int ai=0,bi=0;
read(ai),read(bi);
addl(ai,bi),addl(bi,ai);
}
dfs1(1,0);
top[1]=1;
dfs2(1);
loop(i,1,m){
int ai=0,bi=0;
read(ai),read(bi);
++W[ai];
++W[bi];
W[LCA(ai,bi)]-=2;
}
updateW(1,0);
int res=0;
loop(i,1,n){
if(W[i]==1){
++res;
}
else if(W[i]==0&&i!=1){
res+=m;
}
}
printf("%d\n",res);
return 0;
}