• theory


    http://192.168.102.138/JudgeOnline/problem.php?cid=1274&pid=2

    知识点:1.最大权闭合子图

        2.定义关键点:如果x在闭合图内,则由x通向的任何一个点也一定要在闭合图内,即不存在任何一个闭合子图内的点的出度不在闭合子图内

        3.网络流

        4.做法:正数向S建边,负数向T建边,其它边保留

        5.正数连S的边流为原数,负数连T的边流为原数的相反数,其它边的流量为inf

        6.最后的答案就是(正数和) - (最小割)

    #include <bits/stdc++.h>
    using namespace std;
    const int S = 520,T = 521;
    int T1,n;
    struct edge
    {
        int to;
        int nxt;
    }t1[1010],t2[1010];
    int ct1,ct2 ;
    int head1[1010],head2[1010];
    void add(int x,int y)
    {
        t1[++ct1].nxt = head1[x];
        t1[ct1].to = y;
        head1[x] = ct1;
    }
    void add1(int x,int y)
    {
        t2[++ct2].nxt = head2[x];
        t2[ct2].to = y;
        head2[x] = ct2;
    }
    struct flow
    {
        int to;
        int nxt;
        int len;
    }e[1010];
    int bg[1010],cnt1 = 1;
    void add2(int x,int y,int len)
    {
        e[++cnt1].nxt = bg[x];
        e[cnt1].to = y;
        e[cnt1].len = len;
        bg[x] = cnt1;
    }
    int f[1010];
    int psum = 0;
    int rt = 0;
    int ans = -1;
    int fa[1010];
    int deep[1100];
    queue <int> q;
    int bfs()
    {
        memset(deep,0,sizeof(deep));
        deep[S] = 1;
        q.push(S);
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            for(int i = bg[u];i;i  = e[i].nxt)
            {
                int np = e[i].to;
                if(deep[np] == 0 && e[i].len)
                {
                    deep[np] = deep[u] + 1;
                    q.push(np);
                }
            }
        }
    
        if(deep[T] == 0)return 0;
        else return 1;
    }
    int dfs(int t,int minn)
    {
        if(t == T)
        return minn;
        int tans = 0;
        for(int i = bg[t];i;i = e[i].nxt)
        {
            if(e[i].len)
            {
                int np = e[i].to;
                if(deep[np] == deep[t] + 1)
                {
                    int he1 = dfs(np,min(e[i].len,minn));
                    if(he1)
                    {
                        tans += he1;
                        minn -= he1;
                        e[i].len -= he1;
                        e[i^1].len += he1;
                        if(minn == 0)break;
                    }
                }
            }
        }
        return tans;
    }
    void dfs1(int now,int fat)
    {
        if(fat != 0)add2(now,fat,999999999),add2(fat,now,0);
        for(int i = head1[now];i ;i = t1[i].nxt)
        {
            int to = t1[i].to;
            if(to != fat)dfs1(to,now);    
        }
    } 
    void dfs2(int now,int fat)
    {
        if(fat  != 0)add2(now,fat,999999999),add2(fat,now,0);
        for(int i = head2[now];i ;i = t2[i].nxt)
        {
            int to = t2[i].to;
            if(to != fat)dfs2(to,now);    
        }
    }
    int calc(int t)
    {
        cnt1 = 1;
        memset(bg,0,sizeof(bg));
        dfs1(t,0);
        dfs2(t,0);
        for(int i = 1;i <= n;i++)
        {
            if(f[i] > 0)add2(S,i,f[i]),add2(i,S,0);
            else if(f[i] < 0) add2(i,T,-f[i]),add2(T,i,0);
        }
        int lsp = 0;
        int SUM = 0;
        while(bfs())
        {
            SUM += dfs(S,999999999);
        }
        return psum - SUM;    
    }
    int main()
    {
        scanf("%d",&T1);
        while(T1--)
        {
            scanf("%d",&n);
            for(int i = 1;i <= n;i++)scanf("%d",&f[i]);
            int x,y;
            for(int i = 1;i <= n - 1;i++)
            {
                scanf("%d%d",&x,&y);
                add(x,y),add(y,x);
            }
            for(int i = 1;i <= n - 1;i++)
            {
                scanf("%d%d",&x,&y);
                add1(x,y),add1(y,x);
            }
            for(int i = 1;i <= n;i++)if(f[i] > 0)psum += f[i];
            ans = 0;
            for(int i = 1;i <= n;i++)if(f[i] > 0)ans = max(ans,calc(i));
            printf("%d
    ",ans);
            psum = 0;
            rt = 0;
            ans = 0;
            ct1 = ct2 = 0;
            memset(head1,0,sizeof(head1));
            memset(head2,0,sizeof(head2));
        }    
        return 0;
    }
    #include <bits/stdc++.h>
    using namespace std;
    const int M  = 107;
    const int INF = 1e9+7;
    int rd()
    {
        int xx;
        cin >> xx;
        return xx;
    } 
    int tcas,n,ans;
    int a[M];
    struct edge
    {
        int y,nxt,f;
        edge(int _y=0,int _nxt=0,int _f=0){y=_y;nxt=_nxt;f=_f;}
    };
    struct vec
    {
        int g[M],te;
        edge e[M * 6];
        vec(){te = 1;memset(g,0,sizeof(g));}
        void clear(){te = 1;memset(g,0,sizeof(g));}
        inline void push(int x,int y,int f=0)
        {
            e[++te] = edge(y,g[x],f); 
            g[x] = te;
            e[++te] = edge(x,g[y],0); 
            g[y] = te;
        }
        inline int& operator () (int x){return g[x];}
        inline edge& operator [] (int x){return e[x];}
    }e[2],G;
    int S,T;
    int q[M];
    int lev[M];
    bool bfs()
    {
        int h=0,t=1,x,p,y;
        memset(lev,0,sizeof(lev));
        q[1]=S; lev[S]=1;
        while(h^t)
        {
            x=q[++h];
            for(p=G(x);p;p=G[p].nxt)
            if(G[p].f>0&& !lev[y=G[p].y])
            {
                lev[y]=lev[x]+1;
                if(y==T) return 1;
                q[++t]=y;
            }
        }
        return 0;
    }
    int dinic(int x,int fl)
    {
        if(x==T) return fl;
        int p,y,tp,res=0;
        for(p=G(x);p;p=G[p].nxt)
        if(G[p].f&&lev[x]+1==lev[y=G[p].y])
        {
            tp=dinic(y,min(fl,G[p].f));
            if(tp>0)
            {
                res+=tp;
                fl-=tp;
                G[p].f-=tp;
                G[p^1].f+=tp;
            }
            if(fl==0) return res;
        }
        if(res==0) lev[x]=0;
        return res;
    }
    void dfs(int z,int x,int fa)
    {
        if(fa>0) G.push(x,fa,INF);
        int p,y;
        for(p=e[z](x);p;p=e[z][p].nxt)
        if((y=e[z][p].y)!=fa) dfs(z,y,x);
    }
    int solve(int x)
    {
        int res=0;
        G.clear();
        dfs(0,x,0);
        dfs(1,x,0);
        for(int i = 1;i <= n;i++)
        {
            if(a[i] > 0) G.push(S,i,a[i]),res += a[i];
            else if(a[i] < 0) G.push(i,T,-a[i]);
        }
        while(bfs())
            res-=dinic(S,INF);
        return res;
    }
    int main()
    { 
        tcas=rd();
        while(tcas--)
        {
            n=rd();
            S=0, T=n+1;
            for(int i=1;i<=n;i++) a[i]=rd();
            e[0].clear(), e[1].clear();
            for(int i=1;i<n;i++) e[0].push(rd(),rd());
            for(int i=1;i<n;i++) e[1].push(rd(),rd());
            ans=0;
            for(int i=1;i<=n;i++) ans=max(ans,solve(i));
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    素数筛相关
    ACM-ICPC 2017 Asia Shenyang
    codeforces/contest/1228
    Python 支持的编码格式列表
    Python——json格式数据与字典相互转换
    mysql 数据查询基本语法
    Python 奇葩问题总结;
    Python中的Subprocess模块 python 命令行操作 系统任务管理 执行系统命令
    C++ Json打包数据 查看数据
    mysql数据无法读出 idb文件恢复数据
  • 原文地址:https://www.cnblogs.com/xyj1/p/13678501.html
Copyright © 2020-2023  润新知