zoukankan      html  css  js  c++  java
  • [USACO15DEC]最大流Max Flow

    题目:洛谷P3128。

    题目大意:一棵n个点的树,每次将两个节点最短路径所覆盖的所有节点的流量加1。问你最后流量最大的节点的流量是多少。

    解题思路:裸的树上差分。

    对于每次增加流量,我们把两个节点的流量+1,它们的lca和lca的父亲的流量-1。

    最后求一遍子树和,求出来每个节点的子树和就是该节点实际流量。

    最后求最大值即可。

    时间复杂度:树剖、倍增LCA $O(mlog_2 n)$,Tarjan LCA $O(n+m)$。

    我采用Tarjan算法求LCA,288ms。

    C++ Code:

    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<cctype>
    #define N 50005
    using namespace std;
    int n,m,ne=0,nq=0;
    bool vis[N],instack[N];
    int f[N],head[N],que[N],a[N],zx[N];
    #define C c=getchar()
    inline int readint(){
        char C;
        bool b=false;
        while(!isdigit(c))b=c=='-',C;
        int d=0;
        while(isdigit(c)){
            d=d*10+c-'0';
            C;
        }
        return (b)?(-d):d;
    }
    struct query{
        int same,nxt,to,num;
        bool flag;
    }q[N<<5];
    struct edge{
        int to,nxt;
    }e[N<<5];
    void add_edge(int x,int y){
        e[++ne].to=y;
        e[ne].nxt=head[x];
        head[x]=ne;
        e[++ne].to=x;
        e[ne].nxt=head[y];
        head[y]=ne;
    }
    void add_que(int x,int y,int z){
        q[++nq].to=y;
        q[nq].same=nq+1;
        q[nq].num=z;
        q[nq].nxt=que[x];
        que[x]=nq;
        q[++nq].to=x;
        q[nq].same=nq-1;
        q[nq].num=z;
        q[nq].nxt=que[y];
        que[y]=nq;
    }
    int find(int x){
        if(f[x]==x)return x;
        return f[x]=find(f[x]);
    }
    void tarjan(int root){
        instack[root]=true;
        for(int i=head[root];i;i=e[i].nxt){
            int v=e[i].to;
            if(instack[v])continue;
            tarjan(v);
            f[v]=root;
            vis[v]=true;
        }
        for(int i=que[root];i;i=q[i].nxt)
        if(vis[q[i].to]&&!q[i].flag){
        	int p=find(q[i].to);
            --a[p];
            --a[zx[p]];
            q[i].flag=q[q[i].same].flag=true;
    
        }
        instack[root]=false;
    }
    void dfs(int now){
        instack[now]=true;
        for(int i=head[now];i;i=e[i].nxt)
        if(!instack[e[i].to]){
            dfs(e[i].to);
            a[now]+=a[e[i].to];
        }
    }
    void dfs2(int now){
        instack[now]=true;
        for(int i=head[now];i;i=e[i].nxt)
        if(!instack[e[i].to]){
            zx[e[i].to]=now;
            dfs2(e[i].to);
        }
    }
    int main(){
        n=readint(),m=readint();
        memset(vis,0,sizeof(vis));
        memset(instack,0,sizeof instack);
        for(int i=1;i<=n;i++)f[i]=i;
        for(int i=1;i<n;i++){
            int u=readint(),v=readint();
            add_edge(u,v);
        }
        memset(a,0,sizeof a);
        zx[1]=0;
        dfs2(1);
        memset(instack,0,sizeof instack);
        for(int i=1;i<=m;i++){
            int x=readint(),y=readint();
            ++a[x];
            ++a[y];
            if(x!=y)
            add_que(x,y,i);else
            --a[x],--a[zx[x]];
        }
        tarjan(1);
        memset(instack,0,sizeof instack);
        dfs(1);
        int max=0;
        for(int i=1;i<=n;i++)
        if(max<a[i])max=a[i];
        printf("%d
    ",max);
        return 0;
    }
    
  • 相关阅读:
    228. Summary Ranges
    227. Basic Calculator II
    224. Basic Calculator
    222. Count Complete Tree Nodes
    223. Rectangle Area
    221. Maximal Square
    220. Contains Duplicate III
    219. Contains Duplicate II
    217. Contains Duplicate
    Java编程思想 4th 第4章 控制执行流程
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/7782987.html
Copyright © 2011-2022 走看看