HDU 3879 && BZOJ 1497:Base Station && 最大获利 (最大权闭合图)
http://acm.hdu.edu.cn/showproblem.php?pid=3879
http://www.lydsy.com/JudgeOnline/problem.php?id=1497
题意:给出n个点m条边,其中每个点有一个权值代表修建这个点需要耗费的钱,然后m条边里面,代表如果两个修建好的点相连的话,那么可以得到一点利润。求最大的获利。
思路:和BZOJ 1497是同一道题目。学习最大权闭合图的题目,看了一下不清楚应该怎么建图,然后只好搜一个论文来看看。http://wenku.baidu.com/view/6507a6fe2cc58bd63186bdaf.html
建图:将S与n个点相连,权值为点权,将m条边当成点与T相连,权值为边权,边的两个顶点分别再和化成点的边相连,权值为INF。
闭合图可以解决一些依赖关系,例如这道题目需要有两个顶点才可以得到一条边,边是依赖于两个顶点的形成的。
于是网络是这样的:S->站的点->边的点->T。
我们对这个网络得到的一个割 = 选择的站的花费 + 未选择的边的利润(也可以看作损失的利润),显然这个割集越小越好,即最小割。我们要求的是答案 = 选择的边的利润 - 选择的站的利润。
那么我们一开始可以先累加得到一个选择所有边的利润tot,那么恰好tot - 最小割 = 选择所有边的利润 - 未选择边的利润 - 选择的站的花费 = 选择的边的利润 - 选择的站的利润 = 答案。
所以跑一遍最大流后就用tot - 最大流就可以得到答案了。
记得边的数组要开大一点。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define INF 0x3f3f3f3f
#define N 60010
#define M 350010 // 30w不过
struct Edge {
int u, v, nxt, cap;
Edge () {}
Edge (int u, int v, int nxt, int cap) : u(u), v(v), nxt(nxt), cap(cap) {}
} edge[M];
int head[N], tot, S, T, cur[N], dis[N], gap[N], pre[N]; void Add(int u, int v, int cap) {
edge[tot] = Edge(u, v, head[u], cap); head[u] = tot++;
edge[tot] = Edge(v, u, head[v], ); head[v] = tot++;
} void BFS() {
queue<int> que;
que.push(T);
memset(dis, INF, sizeof(dis));
memset(gap, , sizeof(gap));
gap[]++; dis[T] = ;
while(!que.empty()) {
int u = que.front(); que.pop();
for(int i = head[u]; ~i; i = edge[i].nxt) {
if(dis[edge[i].v] != INF) continue;
dis[edge[i].v] = dis[u] + ;
gap[dis[edge[i].v]]++;
que.push(edge[i].v);
}
}
} int ISAP(int n) {
BFS();
memcpy(cur, head, sizeof(cur));
int u = pre[S] = S, flow, ans = , index, i;
while(dis[S] < n) {
if(u == T) {
flow = INF;
for(i = S; i != T; i = edge[cur[i]].v)
if(flow > edge[cur[i]].cap) flow = edge[cur[i]].cap, index = i;
for(i = S; i != T; i = edge[cur[i]].v)
edge[cur[i]].cap -= flow, edge[cur[i]^].cap += flow;
u = index; ans += flow;
}
for(i = cur[u]; ~i; i = edge[i].nxt) if(edge[i].cap && dis[edge[i].v] + == dis[u]) break;
if(~i) { cur[u] = i; pre[edge[i].v] = u; u = edge[i].v; }
else {
if(--gap[dis[u]] == ) break;
int md = n + ;
for(i = head[u]; ~i; i = edge[i].nxt)
if(edge[i].cap && dis[edge[i].v] < md) md = dis[edge[i].v], cur[u] = i;
gap[dis[u] = md + ]++;
u = pre[u];
}
}
return ans;
} int main() {
int n, m;
while(~scanf("%d%d", &n, &m)) {
memset(head, -, sizeof(head));
tot = ; S = ; T = n + m + ;
for(int i = ; i <= n; i++) {
int w; scanf("%d", &w);
Add(S, i, w); // 源点和站点相连
}
int tot = ;
for(int i = ; i <= m; i++) {
int a, b, c;
scanf("%d%d%d",&a, &b, &c);
tot += c; // 选择边的利润和
Add(i + n, T, c); // 边的点和汇点相连
Add(a, i + n, INF);
Add(b, i + n, INF);
}
printf("%d\n", tot - ISAP(T + ));
}
return ;
}
HDU 3879 && BZOJ 1497:Base Station && 最大获利 (最大权闭合图)的更多相关文章
- hdu - 4971 - A simple brute force problem.(最大权闭合图)
题意:n(n <= 20)个项目,m(m <= 50)个技术问题,做完一个项目能够有收益profit (<= 1000),做完一个项目必须解决对应的技术问题,解决一个技术问题须要付出 ...
- HDU 4971 - A simple brute force problem【最大权闭合图】
有n(20)个工程,完成每个工程获得收益是p[i],m(50)个需要解决的难题,解决每个难题花费是c[i] 要完成第i个工程,需要先解决ki个问题,具体哪些问题,输入会给出 每个难题之间可能有依赖关系 ...
- hdu 3061 hdu 3996 最大权闭合图 最后一斩
hdu 3061 Battle :一看就是明显的最大权闭合图了,水提......SB题也不说边数多少....因为开始时候数组开小了,WA....后来一气之下,开到100W,A了.. hdu3996. ...
- hdu 3879 Base Station 最大权闭合图
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3879 A famous mobile communication company is plannin ...
- BZOJ 1497 最大获利(最大权闭合图)
1497: [NOI2006]最大获利 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 4686 Solved: 2295 [Submit][Statu ...
- 最大权闭合图 && 【BZOJ】1497: [NOI2006]最大获利
http://www.lydsy.com/JudgeOnline/problem.php?id=1497 最大权闭合图详细请看胡伯涛论文<最小割模型在信息学竞赛中的应用>,我在这里截图它的 ...
- BZOJ 1497 JZYZOJ 1344 [NOI2006]最大获利 网络流 最大权闭合图
http://www.lydsy.com/JudgeOnline/problem.php?id=1497 http://172.20.6.3/Problem_Show.asp?id=1344 思路 ...
- hdu 3879 hdu 3917 构造最大权闭合图 俩经典题
hdu3879 base station : 各一个无向图,点的权是负的,边的权是正的.自己建一个子图,使得获利最大. 一看,就感觉按最大密度子图的构想:选了边那么连接的俩端点必需选,于是就以边做点 ...
- 最大获利 HYSBZ - 1497 (最大权闭合图)
最大权闭合图: 有向图,每个点有点权,点权可正可负.对于任意一条有向边i和j,选择了点i就必须选择点j,你需要选择一些点使得得到权值最大. 解决方法: 网络流 对于任意点i,如果i权值为正,s向i连容 ...
随机推荐
- xmpp和OpenFire示例,即时聊天室,支持离线消息
让我说说为什么写这个博客,这是因为我在上周末的研究XMPP和OpenFire,从互联网上下载Demo,但跑不起来.它花了很长的时间.它被改造.抬高.篇博文也是希望后边学习XMPP和OpenFire的同 ...
- 合并ResourceDictionary
原文:合并ResourceDictionary <!--合并资源到资源集合中--> <ResourceDictionary> <ResourceDictionary.Me ...
- WPF Binding的代码实现
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...
- 【WPF】SnapsToDevicePixels与UseLayoutRounding二者到底有什么区别?供参考
原文:[WPF]SnapsToDevicePixels与UseLayoutRounding二者到底有什么区别?供参考 MSDN上解释了一大堆,二者对比来看,并不能发现什么明显的区别,微软爸爸也不知道多 ...
- jquery实现div拖拽
1.引入jquery1.8.3 ,模块拖拽js代码: //模块拖拽 $(function(){ var _move=false;//移动标记 var _x,_y;//鼠标离控件左上角的相对位置 $(& ...
- 【全面解禁!真正的Expression Blend实战开发技巧】第四章 从最常用ButtonStyle开始 - PathButton
原文:[全面解禁!真正的Expression Blend实战开发技巧]第四章 从最常用ButtonStyle开始 - PathButton 上一篇我们介绍了TextButton,但为了追求界面的张力, ...
- Win10《芒果TV》发布两周年纪念特别献礼,陪你度国庆,好礼送不停
2015年芒果TV和微软中国联姻,在Windows10发布之际,共同宣告了Win10版<芒果TV>的诞生,第一个版本于2015年9月30日登陆Windows商店,历经28次迭代,现在她两岁 ...
- 解决iconv函数无法转换某些中文的问题
原文: 解决iconv函数无法转换某些中文的问题 请先看以下代码,这个页面是GB2312编码的: $str = '陶喆';echo 'gb2312-'.$str;echo '<br />' ...
- 使用Newtonsoft.Json输出JSON
安装: Install-Package Newtonsoft.Json 代码: //序列化DataTable DataTable dt = new DataTable(); dt.Columns.Ad ...
- Visual Studio一直弹出“未将对象引用设置到对象的实例”对话框的处理
试了一下,VS2017更新到最新版本的时候,会有这个错误.相当于是相当编辑XAML界面的时候会弹出,程序真正执行的时候反而不会弹出. 应该是最新的VS2017在显示XAML编辑界面的时候,会执行一部分 ...