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

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

倍增求 lca 也写错了活该第一次惨WA。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int const maxn=50005;
int n,m,hd[maxn],ct,f[maxn][20],dep[maxn],s[maxn],mx;
bool vis[maxn];
struct N{
    int to,nxt;
    N(int t=0,int n=0):to(t),nxt(n) {}
}ed[maxn<<1];
void add(int x,int y){ed[++ct]=N(y,hd[x]); hd[x]=ct;}
void dfs0(int x,int fa)
{
    f[x][0]=fa; dep[x]=dep[fa]+1;
    for(int i=1;i<20;i++)f[x][i]=f[f[x][i-1]][i-1];
    for(int i=hd[x],u;i;i=ed[i].nxt)
    {
        if((u=ed[i].to)==fa)continue;
        dfs0(u,x);
    }
}
int lca(int x,int y)
{
    if(dep[x]<dep[y])swap(x,y);
//    for(int i=18;i>=0;i--)
//        if(dep[f[x][i]]>dep[y])x=f[x][i];
//    x=f[x][0];
    int t=dep[x]-dep[y];
    for(int i=18;i>=0;i--)
        if(t&(1<<i))x=f[x][i];
    for(int i=18;i>=0;i--)
//        if(dep[f[x][i]]!=dep[f[y][i]])x=f[x][i],y=f[y][i];
        if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
    if(x==y)return x;
    return f[x][0];
}
void dfs(int x)
{
    for(int i=hd[x],u;i;i=ed[i].nxt)
    {
        if((u=ed[i].to)==f[x][0])continue;
        dfs(u);
        s[x]+=s[u];
    }
    mx=max(mx,s[x]);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1,x,y;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,y); add(y,x);
    }
    dfs0(1,0);
    for(int i=1,x,y;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        int l=lca(x,y);
        s[x]++; s[y]++; s[l]--; s[f[l][0]]--;
    }
    dfs(1);
    printf("%d\n",mx);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Zinn/p/9380683.html
今日推荐