• 【学术篇】树上差分--洛谷3128最大流Max Flow


    懒得贴题目,直接放不稳定的传送门(雾):点击前往暴风城(雾)

    据说这题是BZOJ3490,但本蒟蒻没有权限╮(╯_╰)╭

    这题似乎就是裸树上差分。。。

    对于树上(x,y)之间的路径上的点区间c[i]加k<==>c[x]+=k,c[y]+=k,c[lca(x,y)]-=k,c[father[lca(x,y)]-=k

    就是这样,虽然这题我因为各种智障的原因luogu上交了3遍,为拉低这题通过率做出了巨大的贡献。。。

    最后统计的时候从树根dfs一遍,把子节点的c值加到父节点上就行了~~

    所以这题重点就是求lca(x,y)了,在这里我用了Tarjan,因为比倍增快,而且链剖LCA我也不会(或许也没有Tarjan快)。。

    贴代码:

    #include<cstdio>
    #define N 50005
    #define M 100005
    #define gc getchar
    struct edge
    {
        int to,next;
    }e[N<<1];
    struct ques
    {
        int to,next,id;
    }f[M<<1];
    int n,m,u[N],v[N],c[N],fa[N],up[N],ans[M],tot,tit=0,maxn=0;
    bool vis[N],vis2[N];
    int find(int x)
    {
        return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    void qin(int &a)
    {
        a=0;char c=gc();bool f=0;
        for(;(c<'0'||c>'9')&&c!='-';c=gc());
        if(c=='-') f=1,c=gc();
        for(;c>='0'&&c<='9';c=gc()) a=a*10+c-'0';
        if(f) a=-a;
    }
    void build(int x,int y)
    {
        e[++tot].to=y; e[tot].next=v[x]; v[x]=tot;
        e[++tot].to=x; e[tot].next=v[y]; v[y]=tot;
    }
    void quest(int x,int y,int z)
    {
        f[++tit].to=y; f[tit].next=u[x]; u[x]=tit; f[tit].id=z;
        f[++tit].to=x; f[tit].next=u[y]; u[y]=tit; f[tit].id=z;
    }
    void dfs(int x)
    {
        vis[x]=1; fa[x]=x;
        for(int i=v[x];i;i=e[i].next)
            if(!vis[e[i].to])
                up[e[i].to]=x,dfs(e[i].to),fa[e[i].to]=x;
        for(int i=u[x];i;i=f[i].next)
            if(vis[f[i].to])
                ans[f[i].id]=find(f[i].to);
    }
    void dfs2(int x)
    {
        vis2[x]=1;
        for(int i=v[x];i;i=e[i].next)
        {
            int y=e[i].to;
            if(!vis2[y]) dfs2(y),c[x]+=c[y];
        }
        if(c[x]>maxn) maxn=c[x];
    }
    int main()
    {
        qin(n);qin(m);
        for(int i=1;i<n;i++)
        {
            int a,b;qin(a),qin(b);
            build(a,b);
        }
        for(int i=1;i<=m;i++)
        {
            int a,b;qin(a),qin(b);
            c[a]++;c[b]++;
            quest(a,b,i);
        }
        dfs(1);
        for(int i=1;i<=m;i++)
            c[ans[i]]--,c[up[ans[i]]]--;    
        dfs2(1);
        printf("%d
    ",maxn);
    }

    嗯 就是这样。。。

  • 相关阅读:
    JDBC的异常
    JDBC的事务
    JDBC的数据类型
    JDBC的结果集
    JDBC操作MySQL出现:This result set must come from a statement that was created with a result set type of ResultSet.CONCUR_UPDATABLE, ...的问题解决
    JDBC的Statement对象
    JDBC连接数据库
    JDBC驱动类型
    JDBC实例代码
    java与javax的区别分析(转)
  • 原文地址:https://www.cnblogs.com/enzymii/p/8412163.html
Copyright © 2020-2023  润新知