[USACO15DEC]最大流Max Flow(树链剖分,线段树)

Posted ztz11

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[USACO15DEC]最大流Max Flow(树链剖分,线段树)相关的知识,希望对你有一定的参考价值。

FJ给他的牛棚的N(2≤N≤50,000)个隔间之间安装了N-1根管道,隔间编号从1到N。所有隔间都被管道连通了。

FJ有K(1≤K≤100,000)条运输牛奶的路线,第i条路线从隔间si运输到隔间ti。一条运输路线会给它的两个端点处的隔间以及中间途径的所有隔间带来一个单位的运输压力,你需要计算压力最大的隔间的压力是多少。

思路:

比较基础的树剖题

对于每条线路

我们维护一个区间最大值的线段树

通过树剖实现每个加1的操作

最后读取总最大值就好

代码:

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#define rii register int i
#define rij register int j
using namespace std;
int fa[50005],top[50005],size[50005],nid[50005];
int head[50005],n,k,bnt,cnt,sd[50005],wes[50005];
struct ljb{
    int to,nxt;
}y[100005];
struct tree{
    int maxn,lazy;
}x[800005];
inline int rd(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {f=ch==-?0:1;ch=getchar();}
    while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-0;ch=getchar();}
    return f?x:-x;
}
inline void add(int from,int to)
{
    bnt++;
    y[bnt].to=to;
    y[bnt].nxt=head[from];
    head[from]=bnt;
}
inline void pushdown(int bh)
{
    x[bh*2].lazy+=x[bh].lazy;
    x[bh*2].maxn+=x[bh].lazy;
    x[bh*2+1].lazy+=x[bh].lazy;
    x[bh*2+1].maxn+=x[bh].lazy;
    x[bh].lazy=0;
}
void addjl(int l,int r,int nl,int nr,int bh)
{
    if(l<nl)
    {
        l=nl;
    }
    if(r>nr)
    {
        r=nr;
    }
    if(l==nl&&r==nr)
    {
        x[bh].lazy++;
        x[bh].maxn++;
        return;
    }
    if(x[bh].lazy!=0)
    {
        pushdown(bh);
    }
    int mid=(nl+nr)/2;
    if(l<=mid)
    {
        addjl(l,r,nl,mid,bh*2);
    }
    if(r>mid)
    {
        addjl(l,r,mid+1,nr,bh*2+1);
    }
    x[bh].maxn=max(x[bh*2].maxn,x[bh*2+1].maxn);
}
void dfs1(int wz,int nfa,int nsd)
{
    fa[wz]=nfa;
    sd[wz]=nsd;
    size[wz]=1;
    int maxn=0;
    for(rii=head[wz];i!=0;i=y[i].nxt)
    {
        int to=y[i].to;
        if(to!=nfa)
        {
            dfs1(to,wz,nsd+1);
            size[wz]+=size[to];
            if(size[to]>maxn)
            {
                wes[wz]=to;
                maxn=size[to];
            }
        }
    }
}
void dfs2(int wz,int ntop)
{
    cnt++;
    nid[wz]=cnt;
    top[wz]=ntop;
    if(wes[wz]==0)
    {
        return;
    }
    dfs2(wes[wz],ntop);
    for(rii=head[wz];i!=0;i=y[i].nxt)
    {
        int to=y[i].to;
        if(wes[wz]!=to&&fa[wz]!=to)
        {
            dfs2(to,to);
        }
    }
}
void addlj(int from,int to)
{
    while(top[from]!=top[to])
    {
        if(sd[top[from]]<sd[top[to]])
        {
            swap(from,to);
        }
        addjl(nid[top[from]],nid[from],1,n,1);
        from=fa[top[from]];
    }
    if(sd[from]>sd[to])
    {
        swap(from,to);
    }
    addjl(nid[from],nid[to],1,n,1);
    from=fa[top[from]];
}
int main()
{
//    freopen("1.in","r",stdin);
//    freopen("1.out","w",stdout);
    n=rd(),k=rd();
    for(rii=1;i<n;i++)
    {
        int from,to;
        from=rd(),to=rd();
        add(from,to);
        add(to,from);
    }
    dfs1(1,0,0);
    dfs2(1,1);
    for(rii=1;i<=k;i++)
    {
        int from,to;
        from=rd(),to=rd();
        addlj(from,to);
    }
    cout<<x[1].maxn;
}

 

以上是关于[USACO15DEC]最大流Max Flow(树链剖分,线段树)的主要内容,如果未能解决你的问题,请参考以下文章

[USACO15DEC]最大流Max Flow

洛谷 P3128 [USACO15DEC]最大流Max Flow

洛谷 P3128 [USACO15DEC]最大流Max Flow

P3128 [USACO15DEC]最大流Max Flow

洛谷——P3128 [USACO15DEC]最大流Max Flow

洛谷 P3128 [USACO15DEC]最大流Max Flow