题目描述

小B有n个下属,现小B要带着一些下属让别人拍照。

有m个人,每个人都愿意付给小B一定钱让n个人中的一些人进行合影。如果这一些人没带齐那么就不能拍照,小B也不会得到钱。

注意:带下属不是白带的!!!对于每个下属,如果他带了那么小B需要给他一些钱,保证当他拍照时配合。

请问,小B的净收益最多是多少。

输入输出格式

输入格式:

第1行有2个正整数m和n(0<m,n<=100)。接下来的m行,每行是一个要求拍照的人的有关数据。第一个数是他同意支付该合影的费用;接着是该合影需要的若干下属的编号,以一个0作为行的结束标记。最后一行的n个数是带每个下属的费用。

输出格式:

一个数,表示最大收益。小B可以一个人也不带。

题解

  我们把题目用图的形式表示出来:我们把所有的要求看作是点,每个要求的收益看作是这个点的点权,同理每个人也看作是点,每个人的花费的相反数看作是这个点的点权,然后在每个要求与人之间连接有向边。

  就可发现,我们所求的其实就是这个图的最大权闭合子图。

  首先,我们先来解释一下什么叫做闭合图,所谓最大权闭合图指的是对于一个点集,从这个点集中的点出发的所有出边所指向的点也在这个点集中,则这个点集所组成的图就是一个闭合图。举个例子来说:如下图所示,点集{1,2,3,4,5}和点集{1,2,3,4,5,6}所组成的图都是闭合图,而点集{1,2,3,5,6}就不是一个闭合图(6有一条出边指向了4,但是4没在点集中)。而所谓的最大权,就是指的这样的图中点权和最大的。

  求解最大权的闭合子图我们通常是利用网络流进行求解,我们构造一个超级源点(s),把所有的点权为正的点都与之连边,边的容量为这些点的点权;再构造一个超级汇点(t),把所有的点权为负的点都与之连边,边的容量为点权的相反数,另外,这些点之间原有的边保持不变,边的容量为正无穷。即如下图(黑色为点的编号,红色为权值):

  我们来研究以下两个图之间有什么关系:

  • 在第二个图中,关于s-t的最小割是简单割(割边都与S或T相连),显然他不会去割无穷大的边(黑色的边)。
  • 第二个图的关于s-t的每一个简单割产生的两个子图,我们把含有S的称作S图,含有T的称作T图。则S图是闭合子图。

证明:
简单割中不包含无穷大的边(黑色的边),即不包含联通两个图的边(连接在T点上的边除外)。

所以S图中的边所指向的点一定在S图中,即为闭合图。

  • 最小割产生的S图和T图,S图为最大权闭合子图。

证明:

  因为割集中所有的边,不是连接在s上,就是连接在t上;

  我们记割集中,所有连接在s上的边的权值和为x1,所有连接在t上的边的权值和为x2,而割集中所有边权值和为X=x1+x2;

  又,记图S中所有点的权值和为W,记其中正权值之和为w1,负权值之和为 - w2,故W = w1 - w2;

  而 W + X = w1 - w2 + x1 + x2,由于x2 = w2

    (因为图S中所有负权值的点,必然连接到t点,而图S必然要与t分割开;故割集中,“连接在t点上的边权值和”就是“图S中所有负权值点的权值之和,取负”)

  因而W + X = w1 + x1;

  而显然的,w1 + x1是整个图中所有正权值之和,记为SUM;

  故W = SUM - X,即 “图S中所有点的权值和” = “整个图中所有正权值之和”  - “割集中所有边权值和”;

  然后,因为SUM为定值,只要我们取最小割,则“图S中所有点的权值和”就是最大的,即此时图S为图S为最大权闭合子图。

  所以最大权闭合子图的点权之和等于收益点权之和减去最小割。

代码

#include<bits/stdc++.h>
using namespace std; int w[], c[];
vector <int> G[];
int n, m, x;
const int inf = 0x7fffffff; class Graph{
private :
int cnt;
int Head[], Next[], W[], To[];
int Deep[], cur[];
public :
int s, t, n;
void init()
{
cnt = -;
memset(Head, -, sizeof(Head));
memset(Next, -, sizeof(Next));
}
void _Add(int u, int v, int c)
{
Next[++ cnt] = Head[u];
Head[u] = cnt;
W[cnt] = c;
To[cnt] = v;
}
void Add_edge(int x, int y, int w)
{
_Add(x, y, w);
_Add(y, x, );
}
int Dfs(int u, int flow)
{
if(u == t) return flow;
for(int & i = cur[u]; i != -; i = Next[i])
{
if(Deep[To[i]] == Deep[u] + && W[i] != )
{
int di = Dfs(To[i], min(flow, W[i]));
if(di > )
{
W[i] -= di;
W[i ^ ] += di;
return di;
}
}
}
return ;
}
int Bfs()
{
queue <int> q;
for(; !q.empty();) q.pop();
memset(Deep, , sizeof(Deep));
Deep[s] = ; q.push(s);
for(; !q.empty();)
{
int u = q.front(), v; q.pop();
for(int i = Head[u]; i != -; i = Next[i])
if(!Deep[v = To[i]] && W[i])
{
Deep[v] = Deep[u] + ;
q.push(v);
}
}
return Deep[t] > ? : ;
}
int Dinic()
{
int ans;
for(;Bfs();)
{
for(int i = ; i <= n; ++ i) cur[i] = Head[i];
int d;
for(;d = Dfs(s, inf);) ans += d;
}
return ans;
}
}; Graph Map;
int Num = ;
int n1[], n2[]; void Make_picture()
{
Map.s = ++ Num;
for(int i = ; i <= n; ++ i)
{
n1[i] = ++ Num;
Map.Add_edge(Map.s, Num, w[i]);
}
for(int i = ; i <= m; ++ i) n2[i] = ++ Num;
Map.n = Map.t = ++ Num;
for(int i = ; i <= m; ++ i) Map.Add_edge(n2[i], Map.t, c[i]);
for(int i = ; i <= n; ++ i)
for(int j = ; j < G[i].size(); ++ j)
Map.Add_edge(n1[i], n2[G[i][j]], inf);
return ;
}
int sum = ;
int main()
{
scanf("%d%d", &n, &m);
for(int i = ; i <= n; ++ i)
{
scanf("%d", &w[i]);
sum += w[i];
for(;;)
{
scanf("%d", &x);
if(!x) break;
G[i].push_back(x);
}
}
for(int i = ; i <= m; ++ i) scanf("%d", &c[i]);
Map.init();
Make_picture();
printf("%d\n", sum - Map.Dinic());
return ;
}

参考资料

[1]Dilthey's Blog:最大权闭合子图-[求最大点权的闭合子图]

[2]洛谷【P3410】拍照

【洛谷P3410】拍照题解(最大权闭合子图总结)的更多相关文章

  1. 洛谷 P2762 太空飞行计划问题 P3410 拍照【最大权闭合子图】题解+代码

    洛谷 P2762 太空飞行计划问题 P3410 拍照[最大权闭合子图]题解+代码 最大权闭合子图 定义: 如果对于一个点集合,其中任何一个点都不能到达此集合以外的点,这就叫做闭合子图.每个点都有一个权 ...

  2. 洛谷 P3410 拍照

    洛谷 P3410 拍照 题目描述 小B有n个下属,现小B要带着一些下属让别人拍照. 有m个人,每个人都愿意付给小B一定钱让n个人中的一些人进行合影.如果这一些人没带齐那么就不能拍照,小B也不会得到钱. ...

  3. 洛谷 P3410 拍照(最大流 + 建图)

    这道题问的是一群人要和另一群人合影,每个客人都有必须在场的人全部在场才能在场,每个客人给的有收入,但是邀请也需要支出,问最大收入? 我觉得可以总结为一类问题,就是有先决条件的网络流问题.看到费用和支出 ...

  4. [HOJ2634] How to earn more 最大权闭合子图

    Xiao Ming is an expert in computer science and technology, so he can get a lot of projects every mon ...

  5. HDU 5855 Less Time, More profit 最大权闭合子图

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5855 Less Time, More profit Time Limit: 2000/1000 MS ...

  6. BZOJ1391/LG4177 「CEOI2008」order 最大权闭合子图

    问题描述 BZOJ1391 LG4177 题解 最大权闭合子图,本质是最小割 在任务和机器中间的边之前权值设为INF,代表不可违背这条规则 本题的租借就相当于允许付出一定代价,违背某个规则,只需要把中 ...

  7. 洛谷 - P1361 - 小M的作物 - 最小割 - 最大权闭合子图

    第一次做最小割,不是很理解. https://www.luogu.org/problemnew/show/P1361 要把东西分进两类里,好像可以应用最小割的模板,其中一类A作为源点,另一类B作为汇点 ...

  8. 洛谷 P4174 [NOI2006]最大获利 && 洛谷 P2762 太空飞行计划问题 (最大权闭合子图 && 最小割输出任意一组方案)

    https://www.luogu.org/problemnew/show/P4174 最大权闭合子图的模板 每个通讯站建一个点,点权为-Pi:每个用户建一个点,点权为Ci,分别向Ai和Bi对应的点连 ...

  9. 洛谷 - P2805 - 植物大战僵尸 - 最大流 - 最大权闭合子图

    https://www.luogu.org/problemnew/show/P2805 最大权闭合子图的特点是,假如你要选一个结点,则要先选中它的所有子节点.正权连S负权连T,容量为绝对值,原图有向边 ...

随机推荐

  1. 关于《阿里巴巴Java开发规约》插件的安装与使用

    一.安装 二.idea插件的安装与使用 https://github.com/alibaba/p3c/tree/master/idea-plugin#run-plugin Idea Plugin Pr ...

  2. MySQL5.7 常用用户操作

    目录 MySQL5.7 常用用户操作 1. 新建用户 2. 授权 3. 创建用户时授权 4. 设置与更改用户密码(root) 5. 撤销用户权限 6. 删除用户 7. 查看用户的授权 8. 显示当前用 ...

  3. java多线程——线程池源码分析(一)

    本文首发于cdream的个人博客,点击获得更好的阅读体验! 欢迎转载,转载请注明出处. 通常应用多线程技术时,我们并不会直接创建一个线程,因为系统启动一个新线程的成本是比较高的,涉及与操作系统的交互, ...

  4. SpringIOC的小例子

    IOC IOC--Inversion of Control即控制反转,常常和DI--依赖注入一起被提到. 核心是为了解除程序之间的耦合度. 那么什么样的代码是耦合度高的呢? 假如有个人现在去买苹果 i ...

  5. python学习之老男孩python全栈第九期_第一次周末考试题(over)第三次添加完毕

    day 6python基础数据类型考试题 考试时间:两个半小时 满分100分(80分以上包含80分及格) 一,基础题. 1. 简述变量命名规范(3分) 答:(1) 变量为数字,字母以及下划线的任意组合 ...

  6. django-xss攻击原理与防范

    一.跨站脚本攻击(XSS) XSS是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中.也属一种注入攻击,注入本质上就是把输入的数据变成可执行的程序 ...

  7. 自定义适用于手机和平板电脑的 Dynamics 365(一):主页

    当用户首次打开适用于手机和平板电脑的 Dynamics 365 时,他们将看到默认为“销售仪表板”的主页. 您可以创建新仪表板或 Web 应用程序中编辑现有仪表板,然后为移动设备启用它们,用户可以选择 ...

  8. Asp.net MVC检测到有潜在危险的 Request.Form 值

    解决方法很简单,不像网上说的那么麻烦.只需一步: [ValidateInput(false)] public ActionResult Test(){ }

  9. 绝版Node--Sequlize搭建服务(Node全栈之路)

    绝版Node--Sequlize搭建服务(Node全栈之路) 参考资料:https://itbilu.com/nodejs/npm/VkYIaRPz-.html 准备环境:Mysql,Node 前沿: ...

  10. springcloud 入门 1 (浅谈版本关系)

    SpringCloud: 参考官网:https://projects.spring.io/spring-cloud/            中文版         https://springclou ...