1. 程式人生 > >洛谷3128 [USACO15DEC]最大流Max Flow——樹上差分

洛谷3128 [USACO15DEC]最大流Max Flow——樹上差分

getchar ring www. tar pre ostream pan oid cst

題目:https://www.luogu.org/problemnew/show/P3128

樹上差分。用離線lca,鄰接表存好方便。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=5e4+5,M=1e5+5;
int n,m,hd[N],xnt,fa[N],pre[N],c[N],qhd[N],t[M<<1],nxt[M<<1],ans;
bool vis[N];
struct Ed{ int nxt,to;Ed(int n=0,int t=0):nxt(n),to(t) {} }ed[N<<1]; int rdn() { int ret=0;char ch=getchar(); while(ch>9||ch<0)ch=getchar(); while(ch>=0&&ch<=9)(ret*=10)+=ch-0,ch=getchar(); return ret; } void add(int x,int y) { ed[++xnt]=Ed(hd[x],y);hd[x]=xnt; ed[
++xnt]=Ed(hd[y],x);hd[y]=xnt; } void ad(int x,int y) { t[++xnt]=y;nxt[xnt]=qhd[x];qhd[x]=xnt; t[++xnt]=x;nxt[xnt]=qhd[y];qhd[y]=xnt; } int find(int a){return fa[a]==a?a:fa[a]=find(fa[a]);} void dfs(int cr) { vis[cr]=1; for(int i=qhd[cr],v;i;i=nxt[i]) if(vis[v=t[i]]) {
int lca=find(v),pr=pre[lca]; c[cr]++;c[v]++;c[lca]--;c[pr]--; } for(int i=hd[cr],v;i;i=ed[i].nxt) if((v=ed[i].to)!=pre[cr]) { pre[v]=cr;dfs(v); } fa[cr]=pre[cr]; } void dfsx(int cr) { for(int i=hd[cr],v;i;i=ed[i].nxt) if((v=ed[i].to)!=pre[cr]) dfsx(v),c[cr]+=c[v]; ans=max(ans,c[cr]); } int main() { n=rdn();m=rdn();int x,y; for(int i=1;i<n;i++) { x=rdn();y=rdn();add(x,y); } xnt=0; for(int i=1;i<=m;i++) { x=rdn();y=rdn();ad(x,y); } for(int i=1;i<=n;i++)fa[i]=i; dfs(1);dfsx(1); printf("%d\n",ans); return 0; }

洛谷3128 [USACO15DEC]最大流Max Flow——樹上差分