题目链接:http://hihocoder.com/contest/hiho119/problem/1

题意:中文题意。

由于1≤N≤200,1≤M≤200。最极端情况就是中间所有边都是满的,一共有N*M条边,则最多有40000条边。

对于这样的问题有统一的建图策略,提取出问题的最终形态即可按照如下方式建图:

首先建立源点s和汇点t,将源点s与所有权值为正的点相连,容量为权值;将所有权值为负的点与汇点t相连,容量为权值的绝对值;权值为0的点不做处理;同时将原来的边容量设置为无穷大。

利用结论:最大权闭合子图的权值等于所有正权点之和减去最小割。

证明:

1. 最小割一定是简单割

简单割指得是:割(S,T)中每一条割边都与s或者t关联,这样的割叫做简单割。

因为在图中将所有与s相连的点放入割集就可以得到一个割,且这个割不为正无穷。而最小割一定小于等于这个割,所以最小割一定不包含无穷大的边。因此最小割一定一个简单割。

2. 简单割一定和一个闭合子图对应

闭合子图V和源点s构成S集,其余点和汇点t构成T集。

首先证明闭合子图是简单割:若闭合子图对应的割(S,T)不是简单割,则存在一条边(u,v),u∈S,v∈T,且c(u,v)=∞。说明u的后续节点v不在S中,产生矛盾。

接着证明简单割是闭合子图:对于V中任意一个点u,u∈S。u的任意一条出边c(u,v)=∞,不会在简单割的割边集中,因此v不属于T,v∈S。所以V的所有点均在S中,因此S-s是闭合子图。

由上面两个引理可以知道,最小割也对应了一个闭合子图,接下来证明最小割就是最大权的闭合子图。

首先有割的容量C(S,T)=T中所有正权点的权值之和+S中所有负权点的权值绝对值之和。

闭合子图的权值W=S中所有正权点的权值之和-S中所有负权点的权值绝对值之和。

则有C(S,T)+W=T中所有正权点的权值之和+S中所有正权点的权值之和=所有正权点的权值之和。

所以W=所有正权点的权值之和-C(S,T)

由于所有正权点的权值之和是一个定值,那么割的容量越小,W也就越大。因此当C(S,T)取最小割时,W也就达到了最大权。

 #include <bits/stdc++.h>
using namespace std; typedef struct Edge {
int u, v, w, next;
}Edge; const int inf = 0x7f7f7f7f;
const int maxn = ; int cnt, dhead[maxn];
int cur[maxn], dd[maxn];
Edge dedge[maxn*maxn];
int S, T, N;
int n, m; void init() {
memset(dhead, -, sizeof(dhead));
for(int i = ; i < maxn; i++) dedge[i].next = -;
cnt = ;
} void adde(int u, int v, int w, int c1) {
dedge[cnt].u = u; dedge[cnt].v = v; dedge[cnt].w = w;
dedge[cnt].next = dhead[u]; dhead[u] = cnt++;
dedge[cnt].u = v; dedge[cnt].v = u; dedge[cnt].w = c1;
dedge[cnt].next = dhead[v]; dhead[v] = cnt++;
} bool bfs(int s, int t, int n) {
queue<int> q;
for(int i = ; i < n; i++) dd[i] = inf;
dd[s] = ;
q.push(s);
while(!q.empty()) {
int u = q.front(); q.pop();
for(int i = dhead[u]; ~i; i = dedge[i].next) {
if(dd[dedge[i].v] > dd[u] + && dedge[i].w > ) {
dd[dedge[i].v] = dd[u] + ;
if(dedge[i].v == t) return ;
q.push(dedge[i].v);
}
}
}
return ;
} int dinic(int s, int t, int n) {
int st[maxn], top;
int u;
int flow = ;
while(bfs(s, t, n)) {
for(int i = ; i < n; i++) cur[i] = dhead[i];
u = s; top = ;
while(cur[s] != -) {
if(u == t) {
int tp = inf;
for(int i = top - ; i >= ; i--) {
tp = min(tp, dedge[st[i]].w);
}
flow += tp;
for(int i = top - ; i >= ; i--) {
dedge[st[i]].w -= tp;
dedge[st[i] ^ ].w += tp;
if(dedge[st[i]].w == ) top = i;
}
u = dedge[st[top]].u;
}
else if(cur[u] != - && dedge[cur[u]].w > && dd[u] + == dd[dedge[cur[u]].v]) {
st[top++] = cur[u];
u = dedge[cur[u]].v;
}
else {
while(u != s && cur[u] == -) {
u = dedge[st[--top]].u;
}
cur[u] = dedge[cur[u]].next;
}
}
}
return flow;
} int main() {
// freopen("in", "r", stdin);
int k, u, v, w;
while(~scanf("%d %d", &n, &m)) {
init(); S = ; T = n + m + ; N = T + ;
int pos = ;
for(int i = ; i <= m; i++) {
scanf("%d", &w);
if(w != ) adde(n+i, T, w, );
else adde(n+i, T, inf, );
}
for(int i = ; i <= n; i++) {
scanf("%d %d", &w, &k);
pos += w;
if(w != ) adde(S, i, w, );
else adde(S, i, inf, );
for(int j = ; j < k; j++) {
scanf("%d", &v);
adde(i, n+v, inf, );
}
}
printf("%d\n", pos - dinic(S,T,N));
}
}

[HIHO119]网络流五·最大权闭合子图(最大流)的更多相关文章

  1. [HihoCoder1398]网络流五·最大权闭合子图

    题目大意:有$N$项活动$M$个人,每个活动$act_i$有一个正的权值$a_i$,每个人$stu_i$有一个负的权值$b_i$.每项活动能够被完成当且仅当该项活动所需的所有人到场.如何选择活动使最终 ...

  2. P4177 [CEOI2008]order(网络流)最大权闭合子图

    P4177 [CEOI2008]order 如果不能租机器,这就是最大权闭合子图的题: 给定每个点的$val$,并给出限制条件:如果取点$x$,那么必须取$y_1,y_2,y_3......$,满足$ ...

  3. hdu 5772 String problem 最大权闭合子图

    String problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5772 Description This is a simple pro ...

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

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

  5. hihocoder1398 网络流五之最大权闭合子图

    最大权闭合子图 虽然我自己现在总结不好最大权闭合子图.但也算稍稍理解辣. 网络流起步ing~~~(- ̄▽ ̄)- #include<iostream> #include<cstdio& ...

  6. BZOJ 4873 [Shoi2017]寿司餐厅 | 网络流 最大权闭合子图

    链接 BZOJ 4873 题解 当年的省选题--还记得蒟蒻的我Day1 20分滚粗-- 这道题是个最大权闭合子图的套路题.严重怀疑出题人就是先画好了图然后照着图编了个3000字的题面.和我喜欢的妹子当 ...

  7. Cogs 727. [网络流24题] 太空飞行计划(最大权闭合子图)

    [网络流24题] 太空飞行计划 ★★☆ 输入文件:shuttle.in 输出文件:shuttle.out 简单对比 时间限制:1 s 内存限制:128 MB [问题描述] W 教授正在为国家航天中心计 ...

  8. bzoj1391 最大权闭合子图(also最小割、网络流)

    一道裸的最小割的题,写一下只是练练手. 表示被卡M,RE不开心.一道裸题至于吗? 再次复习一下最大权闭合子图: 1.每一个点若为正权,与源点连一条容量为绝对值权值的边.否则连向汇点一条容量为绝对值权值 ...

  9. P4177 [CEOI2008]order 网络流,最小割,最大权闭合子图

    题目链接 \(Click\) \(Here\) 如果没有租用机器就是一个裸的最大权闭合子图.现在有了租用机器应该怎么办呢? 单独拆点是不行的,因为会和直接买下的情况脱离关系,租借是和连边直接相关的,那 ...

随机推荐

  1. Sublime中增加格式化代码的快捷键

    [Preferences]->[Key Bindings]->[User]中,添加如下: { "keys": ["alt+shift+f"], &q ...

  2. 160912、工具类:spring+springmvc自定义编码转换

    一.自定义的类(注意其中的属性,web.xml中的配置就是根据这个类的) import org.springframework.web.filter.OncePerRequestFilter; imp ...

  3. iOS 学习笔记 一 (2015.02.05)

    一:Xcode6输入框设置为 keyboard type设置为Number Pad弹不出键盘的解决办法   问题:Can't find keyplane that supports type 4 fo ...

  4. [转]clrDateTime to Dynamics AX TransDate

    转自:https://community.dynamics.com/ax/f/33/t/30791.aspx TransDate是一种只有日期,没有时间的类型 utcDateTime=Global:: ...

  5. PHP array_column() 函数

    定义和用法 array_column() 返回输入数组中某个单一列的值. array_column(array,column_key,index_key); 参数 描述 array 必需.规定要使用的 ...

  6. 再谈自主开发与企业IT管理

    前两天写<自主开发与带兵打仗>分析了一下自主开发的利与弊,得到了园内不少朋友的反馈,但我觉得还有很多东西没有交待清楚,可能有很多朋友也跟我一样在公司的IT部门,有自己的研发团队也有很多外购 ...

  7. 使用mysql profiling功能剖析单条查询

    5.1版本开始引入show profile剖析单条语句功能,支持show profiles和show profile语句,参数have_profiling;控制是否开启: 查看是否支持这个功能(查询为 ...

  8. java 编程时候的性能调优

    一.避免在循环条件中使用复杂表达式 在不做编译优化的情况下,在循环中,循环条件会被反复计算,如果不使用复杂表达式,而使循环条件值不变的话,程序将会运行的更快. 例子: import java.util ...

  9. [ios][opengles]OpenGL ES基础知识简介

    参考: http://www.cnblogs.com/shangdahao/archive/2011/11/05/2233587.html 3D变换:模型,视图,投影与Viewport: http:/ ...

  10. ACM题目————Equations

    Description Consider equations having the following form: a*x1^2+b*x2^2+c*x3^2+d*x4^2=0 a, b, c, d a ...