2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 F.Clever King(最大权闭合子图)_2018 acm-icpc 中国大学生程序设计竞赛线上赛 clever king-程序员宅基地

技术标签: acm  网络流  

Description:

In order to increase the happiness index of people's lives, King Y has decided to develop the manufacturing industry vigorously. There are total n kinds of products that King can choose to produce, different products can improve the happiness index of poeple's lives in different degrees, of course, the production of goods needs raw materials, different products need different ore or other products as raw materials. There are total m mines, and each mine can exploit different ore, Therefore, there are m types of ores, the cost of each mining for each mine is different, king Y want to maximize the income, the calculation method of income is:∑increased happiness index - ∑mining costs.

If you choose to exploit a mine, there will be an unlimited number of this kind of ore. What's more, if you produce one product, the happiness index  will definitely increase, no matter how many you produce.

Input:

The first line of the input has an integer T(1<=T<=50), which represents the number of test cases.

In each test case, the first line of the input contains two integers n(1<=n<=200)--the number of the products and m(1<=m<=200)--the number of mines. The second line contains n integers, val[i] indicates the happiness index that number i product can increase. The third line contains m integers, cost[i] indicates the mining cost of number i mine. The next n lines, each line describes the type of raw material needed for the number i product, in each line, the first two integers n1(1<=n1<=m)--the number of ores that this product needs, n2(1<=n2<=n)--the number of products that this product needs, the next n1 + n2 integers indicate the id of ore and product that this product needs. it guarantees that ∑n1+∑n2<=2000.

Output:

Each test case output an integer that indicates the maximum value ∑val[i]-∑cost[i].

忽略每行输出的末尾多余空格
样例输入

2
3 3
600 200 400
100 200 300
1 2 1 2 3
1 0 2
1 0 3
3 4
600 400 200
100 200 300 1000
2 1 1 2 3
1 0 1
1 0 1

样例输出

600
900

思路:
最大权闭合子图,闭合图的概念为:一些点的集合,集合中的点的出边都在这个集合内。如果这些点有权值,则可以找最大权闭合子图
这种模型明显适用于点之间有依赖关系(先后顺序?)的图(DAG等等)
明显是权中有正有负所以我们源点连正权的点,容量为正权,汇点连负权点,容量为父权的绝对值,然后有依赖关系的连边,容量为INF
然后答案是正权之和-最小割(最大流)
证明请看https://wenku.baidu.com/view/986baf00b52acfc789ebc9a9.html
accode

#include<bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
const int MX = 500+4;
const int MS = 500*500+32;
string s[31];
int n,m;
int cost1[MX];
int cost2[MX];
template<class T>
struct Max_Flow
{
    int n;
    int Q[MX],sign;
    int head[MX],level[MX],cur[MX],pre[MX];
    int nxt[MS],pnt[MS],E;
    T cap[MS];
    void init(int n)
    {
        E = 0;
        this->n = n+1;
        fill(head,head+this->n,-1);
    }
    void add(int from, int to,T c,T rw = 0){
        pnt[E] = to;
        cap[E] = c;
        nxt[E] = head[from];
        head[from] = E++;
        pnt[E] = from;
        cap[E] = rw;
        nxt[E] =head[to];
        head[to] = E++;
    }
    bool BFS(int s,int t)
    {
        sign = t;
        std::fill(level,level+n,-1);
        int *front = Q;
        int *tail = Q;
        *tail++ = t;
        level[t] = 0;
        while(front < tail &&level[s] == -1){
            int u = *front++;
            for(int e = head[u];e!=-1;e = nxt[e]){
                if(cap[e^1] > 0&&level[pnt[e]]<0){
                    level[pnt[e]] = level[u]+1;
                    *tail++ = pnt[e];
                }
            }
        }
        return level[s] != -1;
    }
    void Push(int t,T &flow){
        T mi =INF;
        int p = pre[t];
        for(int p = pre[t];p!=-1;p = pre[pnt[p^1]]){
            mi = std::min(mi,cap[p]);
        }
        for(int p = pre[t];p!=-1;p = pre[pnt[p^1]]){
            cap[p] -= mi;
            if(!cap[p]){
                sign = pnt[p^1];
            }
            cap[p^1] += mi;
        }
        flow += mi;
    }
    void DFS(int u,int t, T &flow){
        if(u==t){
            Push(t,flow);
            return ;
        }
        for(int &e = cur[u];e != -1;e = nxt[e]){
             if(cap[e]>0&&level[u]-1==level[pnt[e]]){
                pre[pnt[e]] = e;
                DFS(pnt[e],t,flow);
                if(level[sign] >level[u]){
                    return;
                }
                sign = t;
             }
        }
    }
    T Dinic(int s,int t){
        pre[s] = -1;
        T flow = 0;
        while(BFS(s,t)){
            std::copy(head,head+n,cur);
            DFS(s,t,flow);
        }
        return flow;
    }
};
Max_Flow<LL>F;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
    scanf("%d%d",&n,&m);
        F.init(n+m+2);
        LL sum = 0;
        for(int i = 1;i<=n;i++){
            scanf("%d",&cost1[i]);
            sum += cost1[i];
            F.add(0,i,cost1[i]);
        }
        for(int i = 1;i<=m;i++){
            scanf("%d",&cost2[i]);
            F.add(i+n,n+m+2,cost2[i]);
        }
        for(int i = 1;i<=n;i++){
            int c1,c2;
            scanf("%d%d",&c1,&c2);
            for(int j = 0;j<c1;j++){
                int x;
                scanf("%d",&x);
                F.add(i,x+n,INF);
            }
            for(int j = 0;j<c2;j++){
                int x;
                scanf("%d",&x);
                F.add(i,x,INF);
            }
        }
        LL ans = F.Dinic(0,n+m+2);
     //   cout<<ans<<endl;
        printf("%ld\n",sum-ans);

    }
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/w571523631/article/details/80238770

智能推荐

Flutter mixin混入_flutter mixin 混入 mixin-程序员宅基地

文章浏览阅读127次。flutter mixin_flutter mixin 混入 mixin

Windows Terminal美化界面,优雅的办公带来超高的效率_aka terminal美化-程序员宅基地

文章浏览阅读888次。贴个图众所周知,Windows Terminal没有美化后那个傻大蓝,沉默黑简直不忍直视。没有像官方演示的那么美观(所以得自己捯饬捯饬好看的样子)美化开始第一步安装相关的模块和PowerLine主题Install-Module posh-git -Scope CurrentUserInstall-Module oh-my-posh -Scope CurrentUser如果你使用管理员权限打开PowerShell并且想把oh-my-posh安装到所有用户,则输入Install-Module _aka terminal美化

Qt编写控件属性设计器-程序员宅基地

文章浏览阅读435次。一、前言自从研究Qt编写自定义控件以来,一发不可收拾,越多越多人有类似的需求找我定制控件,陆陆续续写了上百个控件,目前已超过150个,于是逐渐衍生了另外一个需求,提供一个控件属性设计器,类似QtDesigner一样,可以方便的拖曳控件,改变属性,立即应用,并导出到文件方便下次直接加载,这个设计器有点像组态中的一个雏形,提供了基本的加载控件,导入导出数据,数据源绑定等。本系列文章将从加..._qt实现属性编辑

lopatkin俄大神精简中文系统Windows 10 1607 Enterprise LTSB 2016 x86-x64 ZH-CN 2x1-程序员宅基地

文章浏览阅读5.6k次。撸了今年阿里、头条和美团的面试,我有一个重要发现.......>>> ..._win10 1607 俄罗斯

后台服务守护进程神器pm2介绍及使用_pm2 执行go命令-程序员宅基地

文章浏览阅读1.4k次。linux的后台服务程序需要在后台一直运行。如果通过ssh访问临时启动的,会话一结束就直接关闭了服务。想让服务在后台一直运行且永远不挂掉,推荐后台服务守护进程神器pm2,强大且适用于各种语言的后台服务程序。_pm2 执行go命令

深度桌面操作系统架构设计-程序员宅基地

文章浏览阅读2.5k次,点赞4次,收藏23次。作者 | ManateeLazyCat 链接 |https://my.oschina.net/ManateeLazyCat/blog/831104今天就结合深度桌面操作系统给大家..._x11/xcb

随便推点

几何矩求解椭圆_二阶矩确认椭圆-程序员宅基地

文章浏览阅读974次。勒让德惯性椭圆求解1.matlab利用二阶矩求解椭圆长轴、短轴、离心率、长轴与x轴夹角xbar=stats(k).Centroid(1);%区域的重心坐标ybar = stats(k).Centroid(2); x = list(:,1) - xbar; y = -(list(:,2) - ybar); % This is negative for the % orientation calculation (measured in the % counter-clockwise dire_二阶矩确认椭圆

《Python编程》专栏简介-程序员宅基地

文章浏览阅读155次。在本教程中,我们涵盖了Python编程的主要主题,包括Python基础知识、Python数学、Python网络编程、Python算法和数据结构、Python机器学习、Python Web开发和Python游戏开发。

在Ubuntu 12.04 64 位 搭载Android4.4源码编译环境-程序员宅基地

文章浏览阅读67次。在Ubuntu 12.04 64 位 搭载Android4.4源码编译环境 一、准备工作:(1) VMare Workstation 10(2)Ubuntu12.04 64bit(3) JDK1.6(4)Android 4.4 源码(PS:...

图像数据增广_图像增广-程序员宅基地

文章浏览阅读1.2k次,点赞19次,收藏24次。本文主要介绍了图像数据的几种增广方式,其中包括随机翻转、随机裁剪和随机颜色变换等,使用时一般在训练集上综合使用以达到鲁棒效果。_图像增广

8种编程语言对比,究竟谁更好用_算法用什么语言写比较好-程序员宅基地

文章浏览阅读977次。8种编程语言对比,究竟谁更好用_算法用什么语言写比较好

数据库oracle实际使用的内存---AIX产生大量的swap反思_oracle数据库内存64,sga40,会占用swap吗-程序员宅基地

文章浏览阅读796次。来看看oracle实际使用的内存:select sum(pga_alloc_mem)/1024/1024/1024 Alloc from v$process ; +select sum(value)/1024/1024/1024 as b from v$sga + 进程本身消耗的内存。操作系统频繁使用swap,原因基本是系统内存不够用了。从数据库的内存配置来看,128G总内..._oracle数据库内存64,sga40,会占用swap吗