题解——洛谷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;
}

 

posted @ 2018-08-06 21:37  dreagonm  阅读(186)  评论(0编辑  收藏  举报