P3128 [USACO15DEC]最大流Max Flow (树上差分)

传送门

倍增求LCA+树上差分

典型的树上差分题,根据书上差分的思想,w[u]和w[v]分别加1,它们的最近公共祖先(LCA)和LCA的父亲各减1,最后dfs求和。

#include
#include
#include
#include
#include
#include
#define mems(a,b) memset(a,b,sizeof(a))

using namespace std;
const int N=5e4+30;

int head[N],d[N],pa[N][25],dis[N],cnt[N];
int tot;
struct node{
    int v,next;
}s[N*2];
void add(int u,int v)
{
    s[tot].v=v;
    s[tot].next=head[u];
    head[u]=tot++;
}
void init()
{
    tot=0;
    mems(head,-1);
    mems(d,0);
    mems(dis,0);
    mems(pa,0);
}
void dfs1(int u,int fa,int len)
{
    d[u]=d[fa]+1;//深度
    dis[u]=len;//到根节点距离
    pa[u][0]=fa;
    for(int i=1;(1<d[b])
        swap(a,b);
    for(int i=20;i>=0;i--)
    {
        if(d[a]<=d[b]-(1<=0;i--)
    {
        if(pa[a][i]==pa[b][i])
            continue;
        else
        {
            a=pa[a][i];
            b=pa[b][i];
        }
    }
    return pa[a][0];
}
void dfs2(int u,int fa)
{
    for(int i=head[u];~i;i=s[i].next)
    {
        int v=s[i].v;
        if(v==fa)
            continue;
        dfs2(v,u);
        cnt[u]+=cnt[v];
    }
}
int main()
{
    int n,k;
    init();
    scanf("%d%d",&n,&k);
    for(int i=1;i

 

你可能感兴趣的:(【最近公共祖先LCA】,树上差分)