题解——洛谷P3128 [USACO15DEC]最大流Max Flow
裸的树上差分
因为要求点权所以在点上差分即可
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int MAXN = 50110; const int MAXM = 100100; const int MAXlog = 18; int cnt=0,u[MAXN*2],v[MAXN*2],first[MAXN],next[MAXN*2]; int cf[MAXN]; int dep[MAXN],jump[MAXN][MAXlog+2]; int n,k; void addedge(int ux,int vx){ cnt++; u[cnt]=ux; v[cnt]=vx; next[cnt]=first[ux]; first[ux]=cnt; } void dfs(int u,int f){ dep[u]=dep[f]+1; jump[u][0]=f; for(int i=1;i<=MAXlog;i++) jump[u][i]=jump[jump[u][i-1]][i-1]; for(int i=first[u];i;i=next[i]) if(v[i]!=f) dfs(v[i],u); } int lca(int x,int y){ if(dep[x]<dep[y]) swap(x,y); for(int i=MAXlog;i>=0;i--) if(dep[x]-(1<<i)>=dep[y]) x=jump[x][i]; if(x==y) return x; for(int i=MAXlog;i>=0;i--) if(jump[x][i]!=jump[y][i]){ x=jump[x][i]; y=jump[y][i]; } return jump[x][0]; } int ans=0; void dfs2(int u,int f){ for(int i=first[u];i;i=next[i]){ if(v[i]==f) continue; dfs2(v[i],u); cf[u]+=cf[v[i]]; } if(cf[u]>ans) ans=cf[u]; } int main(){ scanf("%d %d",&n,&k); for(int i=1;i<=n-1;i++){ int a,b; scanf("%d %d",&a,&b); addedge(a,b); addedge(b,a); } dfs(1,0); for(int i=1;i<=k;i++){ int a,b; scanf("%d %d",&a,&b); cf[a]++; cf[b]++; int l=lca(a,b); cf[l]-=1; cf[jump[l][0]]-=1; } dfs2(1,0); printf("%d",ans); return 0; }