计蒜客 修建机场 解题报告
来源:互联网 发布:淘宝店铺等级快速升级 编辑:程序博客网 时间:2024/04/20 10:13
在蒜头君生活的王国有 nnn 座城市,他们的王国计划在这些城市中修建机场,以方便国民的交通。
第 iii 座城市修建机场的费用为 pip_ipi。如果某两个城市aaa 和 bbb 都修建机场,那么这两个城市的市民就可以很方便地到达对方城市,可以为国家带来的收益为 ccc。求修建机场之后的总收益减去修建机场的总费用的最大值。
输入格式
输入最多包含 202020 组测试数据,以 EOF 结束。对于每组测试数据:
第一行包含两个整数 n,mn,mn,m(1≤n≤5000;1≤m≤500001 \leq n \leq 5000 ; 1 \leq m \leq 500001≤n≤5000;1≤m≤50000),其中mmm 表示可以带来收益的城市对数。
第二行包含 nnn 个整数 pip_ipi(pi≤1000000p_i \leq 1000000pi≤1000000)。
接下来 mmm 行每行包含三个整数 a,b,ca,b,ca,b,c(1≤a,b≤n;c≤10000001 \leq a , b \leq n ; c \leq 10000001≤a,b≤n;c≤1000000)。
输出格式
对于每组测试数据,输出一个整数。
样例输入
5 55 4 3 2 11 2 42 3 23 4 34 5 43 5 34 15 5 5 51 2 1
样例输出
40
网络流,最大闭合子图,讲解地址如下:http://www.hihocoder.com/contest/hiho119/problems
建图思路如下:
因为获利=收入-代价,我们需要求的就是使代价最小,我们先假设获得 了全部的收入,这样接下来就容易算代价 假设S割表示被选择了,T割表示没有被选择
做法一:
为每条边建一个新的结点Ci(注意与收入的Ci区分),S向这个结点连容量 为Ci的边表示如果没在S割会造成Ci的代价(也就是相当于收入的逆运 算),此外Ci向这条边所连接的两个点Ai和Bi连一条容量为无穷大的边, 表示如果选了这条边则两侧的点也必须要选。 原来的点向T连一条容量为Pi的边表示如果在S割会造成Pi的代价
代码如下:
#include <bits/stdc++.h>using namespace std;#define maxn 100005const int inf = 100000007;#define ll long longstruct node{ int to,next; ll flow;};node edge[1000000];int head[maxn<<1],layer[maxn<<1],cnt,n,m,E;ll ans;//注意用long long bool bfs(){ queue<int>q; memset(layer,-1,sizeof(layer)); layer[0]=0; q.push(0); while(!q.empty()){ int now=q.front(); q.pop(); if(now==E)return true; for(int i=head[now];i!=-1;i=edge[i].next){ if(edge[i].flow && layer[edge[i].to]==-1){ layer[edge[i].to]=layer[now]+1; q.push(edge[i].to); } } } return false;}ll dfs(int pow,ll flow){ ll sum=0; if(pow==E)return flow; for(int i=head[pow];i!=-1;i=edge[i].next){ if(edge[i].flow && layer[edge[i].to]==layer[pow]+1){ ll temp=dfs(edge[i].to,min(edge[i].flow,flow-sum)); edge[i].flow-=temp; edge[i^1].flow+=temp; sum+=temp; if(sum==flow)return sum; } } if(!sum)layer[pow]=-1; return sum;}int dinic(){ while(bfs())ans-=dfs(0,inf);}void add(int s,int e,ll flow){ edge[cnt].flow=flow; edge[cnt].to=e; edge[cnt].next=head[s]; head[s]=cnt++; edge[cnt].flow=0; edge[cnt].to=s; edge[cnt].next=head[e]; head[e]=cnt++;}int main(){ while(cin>>n>>m){ E=n+m+1; memset(head,-1,sizeof(head)); cnt=0; for(int i=1;i<=n;i++){ int temp; scanf("%d",&temp); add(i,E,temp); } ans=0; for(int i=1;i<=m;i++){ int s,e,v; scanf("%d%d%d",&s,&e,&v); ans+=v; add(0,i+n,v); add(i+n,s,inf); add(i+n,e,inf); } dinic(); cout<<ans<<endl; }}
阅读全文
0 0
- 计蒜客 修建机场 解题报告
- noi2011道路修建解题报告
- 计蒜客 排涝 解题报告
- 计蒜客 填志愿 解题报告
- 韩国拟在独岛修建机场 可有效控制争议海域
- 解题报告
- 解题报告
- 解题报告
- 解题报告
- 解题报告
- 解题报告
- 解题报告
- 计蒜客—— 修建大桥
- Antiprime解题报告
- expr解题报告
- 华容道解题报告
- tju解题报告
- zju1062/pku1095解题报告
- 算法谜题119 有色三格板平铺
- php之路
- 自定义Mysql连接池
- 02-线性结构2 一元多项式的乘法与加法运算 (20分)
- qwb与支教 二分
- 计蒜客 修建机场 解题报告
- 电商市场的全面铺设,农村淘宝开始升级
- 不能上网,能ping通IP,解决办法
- 商用室内机器人才是未来机器人开发的热点与趋势
- Kvm-Qemu
- 继承(二)--菱形继承,虚拟虚拟继承
- 代理模式1
- Leetcode 23. Merge k Sorted Lists合并k个排序链表
- NEXUS 5 工厂镜像刷机教程及刷机包目录解析