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

智能推荐

力扣平衡二叉搜索树的创建:将有序数组转换为二叉搜索树-程序员宅基地

文章浏览阅读214次,点赞6次,收藏3次。其中mid的使用非常值得记忆。

QT设置QLabel中字体的颜色_qolable 字体颜色-程序员宅基地

文章浏览阅读8k次,点赞2次,收藏6次。QT设置QLabel中字体的颜色其实,这是一个比较常见的问题。大致有几种做法:一是使用setPalette()方法;二是使用样式表;三是可以使用QStyle;四是可以在其中使用一些简单的HTML样式。下面就具体说一下,也算是个总结吧。第一种,使用setPalette()方法如下:QLabel *label = new QLabel(tr("Hello Qt!"));QP_qolable 字体颜色

【C#】: Import “google/protobuf/timestamp.proto“ was not found or had errors.问题彻底被解决!_import "google/protobuf/timestamp.proto" was not f-程序员宅基地

文章浏览阅读3.7k次。使用C# 作为开发语言,将pb文件转换为cs文件的时候相信很多人都会遇到一个很棘手的问题,那就是protoc3环境下,import Timestamp的问题,在头部 import “google/protobuf/timestamp.proto”;的时候会抛异常:google/protobuf/timestamp.proto" was not found or had errors;解决办法【博主「pamxy」的原创文章的分享】:(注:之后才发现,不需要添加这个目录也可以,因为timestamp.p_import "google/protobuf/timestamp.proto" was not found or had errors.

安卓抓取JD wskey + 添加脚本自动转换JD cookie_jd_wsck-程序员宅基地

文章浏览阅读4.1w次,点赞9次,收藏98次。一、准备工具: 1. app:VNET(抓包用)、京东; 安卓手机需要下载VNET软件。下载官网:https://www.vnet-tech.com/zh/ 2. 已安装部署好的青龙面板;二、抓包wskey: 1. 打开已下载的VNET软件,第一步先安装CA证书; 点击右下角三角形按钮(开始抓包按钮),会提示安装证书,点击确定即可,app就会将CA证书下载至手机里,随后在手机设置里进行安装,这里不同手机可能安装位置不同,具体..._jd_wsck

Mybatis-Plus自动填充失效问题:当字段不为空时无法插入_mybatisplus插入不放为空的字段-程序员宅基地

文章浏览阅读2.9k次,点赞7次,收藏3次。本文针对mybatis-plus自动填充第一次更新能正常填充,第二次更新无法自动填充问题。????mybatis-plus自动填充:当要填充的字段不为空时,填充无效问题的解决????先上一副官方的图:取自官方:https://mp.baomidou.com/guide/auto-fill-metainfo.html第三条注意事项为自动填充失效原因:MetaObjectHandler提供的默认方法的策略均为:如果属性有值则不覆盖,如果填充值为null则不填充以官方案例为例:```java_mybatisplus插入不放为空的字段

Matlab 生成exe执行文件_matlab exe-程序员宅基地

文章浏览阅读1w次,点赞25次,收藏94次。利用 Application Complier 完成MATLAB转exe文件_matlab exe

随便推点

Python Seaborn或者Matplotlib作图:改变x、y轴标签的字体大小(xlabel,ylabel)_plt.xlabel字体大小-程序员宅基地

文章浏览阅读1.2w次,点赞8次,收藏19次。如题。给出在seaborn或者matplotlib作图这2种情况下的解决方案。_plt.xlabel字体大小

树状数组 POJ 2352 Star-程序员宅基地

文章浏览阅读907次。#include #include using namespace std;#define SIZE 320010#define CLR( arr, val ) memset( arr, val, sizeof(arr) )int tree[SIZE];int level[SIZE];int max_size;int lowBit( int index ){

MIT-BEVFusion系列五--Nuscenes数据集详细介绍,有下载好的图片_nuscense数据集-程序员宅基地

文章浏览阅读2.3k次,点赞29次,收藏52次。nuScenes 数据集 (pronounced /nu:ːsiː:nz/) 是由 Motional (以前称为 nuTonomy) 团队开发的自动驾驶公共大型数据集。nuScenes 数据集的灵感来自于开创性的 KITTI 数据集。nuScenes 是第一个提供自动驾驶车辆整个传感器套件 (6 个摄像头、1 个 LIDAR、5 个 RADAR、GPS、IMU) 数据的大型数据集。与 KITTI 相比,nuScenes 包含的对象注释多了 7 倍。_nuscense数据集

python mqtt publish_Python Paho MQTT:无法立即在函数中发布-程序员宅基地

文章浏览阅读535次。我正在实现一个程序,该程序可以侦听特定主题,并在ESP8266发布新消息时对此做出反应.从ESP8266收到新消息时,我的程序将触发回调并执行一系列任务.我在回调函数中发布了两条消息,回到了Arduino正在侦听的主题.但是,仅在函数退出后才发布消息.谢谢您的所有宝贵时间.我试图在回调函数中使用loop(1),超时为1秒.该程序将立即发布该消息,但似乎陷入了循环.有人可以给我一些指针如何在我的回调..._python 函数里面 mqtt调用publish方法 没有效果

win11怎么装回win10系统_安装win10后卸载win11-程序员宅基地

文章浏览阅读3.4w次,点赞16次,收藏81次。微软出来了win11预览版系统,很多网友给自己的电脑下载安装尝鲜,不过因为是测试版可能会有比较多bug,又只有英文,有些网友使用起来并不顺畅,因此想要将win11退回win10系统。那么win11怎么装回win10系统呢?今天小编就教下大家win11退回win10系统的方法。方法一:1、首先点击开始菜单,在其中找到“设置”2、在设置面板中,我们可以找到“更新和安全”3、在更新和安全中,找到点击左边栏的“恢复”4、恢复的右侧我们就可以看到“回退到上版本的win10”了。方法二:_安装win10后卸载win11

SQL Server菜鸟入门_sql server菜鸟教程-程序员宅基地

文章浏览阅读3.3k次,点赞2次,收藏3次。数据定义_sql server菜鸟教程

推荐文章

热门文章

相关标签