POJ 3417(Acwing 352)——闇の連鎖
树上差分+树剖LCA
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; const int N = 1e5+10,M=2*2e5+10; struct Edge{ int to,next,w; }edge[M];int idx; int h[N]; int n,m; int f[N]; int size[N],fa[N],son[N]; int top[N],dep[N]; void add(int u,int v) { edge[++idx].to=v; edge[idx].next=h[u]; h[u]=idx; } void dfs1(int s,int f) { fa[s]=f; size[s]=1; dep[s]=dep[f]+1; int wson=-1; for(int i=h[s];~i;i=edge[i].next) { int to=edge[i].to; if(to==f)continue; dfs1(to,s); size[s]+=size[to]; if(size[to]>wson)wson=size[to],son[s]=to; } } void dfs2(int s,int t) { top[s]=t; if(!son[s])return; dfs2(son[s],t); for(int i=h[s];~i;i=edge[i].next) { int to=edge[i].to; if(to==fa[s] || to==son[s])continue; dfs2(to,to); } } inline int lca(int a,int b) { while(top[a]!=top[b]) { if(dep[top[a]]<dep[top[b]])swap(a,b); a=fa[top[a]]; } return dep[a]<dep[b] ? a : b; } void dfs(int k) { for(int i=h[k];~i;i=edge[i].next) { int to=edge[i].to; if(to==fa[k])continue; dfs(to); f[k]+=f[to]; } } void init() { memset(h,-1,sizeof h); } int main() { scanf("%d%d",&n,&m); init(); for(int i=1;i<=n-1;i++) { int a,b;scanf("%d%d",&a,&b); add(a,b); add(b,a); } dfs1(1,0); dfs2(1,1); for(int i=1;i<=m;i++) { int a,b;scanf("%d%d",&a,&b); f[a]++;f[b]++; f[lca(a,b)]-=2; } dfs(1); int ans=0; for(int i=2;i<=n;i++) { if(f[i]==0)ans+=m; else if(f[i]==1)ans++; else continue; } printf("%d\n",ans); return 0; }

浙公网安备 33010602011771号