• [LUOGU] P3128 [USACO15DEC]最大流Max Flow


    题意:一棵树,多次给指定链上的节点加1,问最大节点权值

    n个点,n-1条边很容易惯性想成一条链,幸好有样例..

    简单的树剖即可!(划去)

    正常思路是树上差分,毕竟它就询问一次..

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    
    using namespace std;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    const int MAXN=500005<<2;
    
    struct Edge{
        int next,to;
        Edge(int x=0,int 
        y=0){next=x;to=y;}
    }e[MAXN];
    int ecnt,head[MAXN];
    inline void add(int x,int y){
        e[++ecnt]=Edge(head[x],y);
        head[x]=ecnt;
    }
    
    int n,m;
    
    int fa[MAXN],dep[MAXN],siz[MAXN],hs[MAXN];
    void dfs1(int x,int pre){
        fa[x]=pre;dep[x]=dep[pre]+1;siz[x]=1;
        int mx=0,tmp=0;
        for(int i=head[x];i;i=e[i].next){
            int v=e[i].to;
            if(v==pre) continue;
            dfs1(v,x);
            siz[x]+=siz[v];
            if(siz[v]>mx){mx=siz[v];tmp=v;}
        }
        hs[x]=tmp;
    }
    
    int top[MAXN],id[MAXN],tot;
    void dfs2(int x,int tp){
        top[x]=tp;id[x]=++tot;
        if(hs[x]) dfs2(hs[x],tp);
        for(int i=head[x];i;i=e[i].next){
            int v=e[i].to;
            if(v==fa[x]||v==hs[x]) continue;
            dfs2(v,v);
        }
    }
    
    int lca(int x,int y){
        int ret;
        while(top[x]!=top[y]){
            dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]];
        }
        return dep[x]<dep[y]?x:y;
    }
            
    int ans,sum[MAXN];
    void dfs(int cur){
        for(int i=head[cur];i;i=e[i].next){
            int v=e[i].to;
            if(v==fa[cur]) continue;
            dfs(v);
            sum[cur]+=sum[v];
        }
        ans=max(sum[cur],ans);
    }
                    
    
    int main(){
        n=rd();m=rd();
        int x,y,t;
        for(int i=1;i<=n-1;i++){
            x=rd();y=rd();
            add(x,y);add(y,x);
        }
        dfs1(1,0);
        dfs2(1,1);
        for(int i=1;i<=m;i++){
            x=rd();y=rd();t=lca(x,y);
            sum[x]+=1;sum[y]+=1;
            sum[t]-=1;sum[fa[t]]-=1;
        }
        dfs(1);
        cout<<ans<<endl;
        return 0;
    }
    树上差分
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    
    using namespace std;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    const int MAXN=500005<<2;
    
    struct Edge{
        int next,to;
        Edge(int x=0,int 
        y=0){next=x;to=y;}
    }e[MAXN];
    int ecnt,head[MAXN];
    inline void add(int x,int y){
        e[++ecnt]=Edge(head[x],y);
        head[x]=ecnt;
    }
    
    int n,m;
    
    struct Seg{
        #define ls (cur<<1)
        #define rs (cur<<1|1)
        #define mid (l+r>>1)
        int mx[MAXN],add[MAXN];
        Seg(){memset(mx,0,sizeof(mx));memset(add,0,sizeof(add));}
        void pushup(int cur){
            mx[cur]=max(mx[ls],mx[rs]);
        }
        void pushdown(int cur,int l,int r){
            int v=add[cur];
            add[ls]+=v;add[rs]+=v;
            mx[ls]+=v;mx[rs]+=v;
            add[cur]=0;
        }
        void build(int cur,int l,int r){
            if(l==r) {mx[cur]=0;return;}
            build(ls,l,mid);build(rs,mid+1,r);
            pushup(cur);
        }
        void update(int L,int R,int cur,int l,int r,int w){
            if(L<=l&&r<=R){mx[cur]+=w;add[cur]+=w;return;}
            pushdown(cur,l,r);
            if(L<=mid) update(L,R,ls,l,mid,w);
            if(mid <R) update(L,R,rs,mid+1,r,w);
            pushup(cur);
        }
    }T;
    
    int fa[MAXN],dep[MAXN],siz[MAXN],hs[MAXN];
    void dfs1(int x,int pre){
        fa[x]=pre;dep[x]=dep[pre]+1;siz[x]=1;
        int mx=0,tmp=0;
        for(int i=head[x];i;i=e[i].next){
            int v=e[i].to;
            if(v==pre) continue;
            dfs1(v,x);
            siz[x]+=siz[v];
            if(siz[v]>mx){mx=siz[v];tmp=v;}
        }
        hs[x]=tmp;
    }
    
    int top[MAXN],id[MAXN],tot;
    void dfs2(int x,int tp){
        top[x]=tp;id[x]=++tot;
        if(hs[x]) dfs2(hs[x],tp);
        for(int i=head[x];i;i=e[i].next){
            int v=e[i].to;
            if(v==fa[x]||v==hs[x]) continue;
            dfs2(v,v);
        }
    }
    
    void updateLink(int x,int y,int w){
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            T.update(id[top[x]],id[x],1,1,n,w);
            x=fa[top[x]];
        }
        if(dep[x]>dep[y]) swap(x,y);
        T.update(id[x],id[y],1,1,n,w);
    }
            
    
    int main(){
        n=rd();m=rd();
        int x,y;
        for(int i=1;i<=n-1;i++){
            x=rd();y=rd();
            add(x,y);add(y,x);
        }
        dfs1(1,0);
        dfs2(1,1);
        T.build(1,1,n); 
        for(int i=1;i<=m;i++){
            x=rd();y=rd();
            updateLink(x,y,1);
        }
        cout<<T.mx[1];
        return 0;
    }
    树剖

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9380643.html

  • 相关阅读:
    Python进程、线程
    Maven项目的坐标GroupId和ArtifactId
    java中的变量
    java中new一个对象的执行过程及类的加载顺序
    java中string和int互相转化
    什么是设计模式?
    Mybatis解决了JDBC编程哪些问题
    SQL注入、占位符拼接符
    JDBC、事务和连接池
    关于Spring配置文件xml文档的schema约束
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9380643.html
Copyright © 2020-2023  润新知