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

题目: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
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/Narh/p/9380665.html