BZOJ_P1497&Codevs_P1789 最大获利(最大权闭合图最小割最大流)
来源:互联网 发布:seo 知乎 编辑:程序博客网 时间:2024/06/06 10:46
最大获利 2006年NOI全国竞赛
时间限制: 2 s
空间限制: 128000 KB
题目等级 : 大师 Master
题目描述 Description
新的技术正冲击着手机通讯市场,对于各大运营商来说,这既是机遇,更是 挑战。THU 集团旗下的 CS&T 通讯公司在新一代通讯技术血战的前夜,需要做 太多的准备工作,仅就站址选择一项,就需要完成前期市场研究、站址勘测、最 优化等项目。 在前期市场调查和站址勘测之后,公司得到了一共 N 个可以作为通讯信号中 转站的地址,而由于这些地址的地理位置差异,在不同的地方建造通讯中转站需 要投入的成本也是不一样的,所幸在前期调查之后这些都是已知数据:建立第 i 个通讯中转站需要的成本为 Pi(1≤i≤N)。 另外公司调查得出了所有期望中的用户群,一共 M 个。关于第 i 个用户群的 信息概括为 Ai, Bi和 Ci:这些用户会使用中转站 Ai和中转站 Bi进行通讯,公司 可以获益 Ci。(1≤i≤M, 1≤Ai, Bi≤N) THU 集团的 CS&T 公司可以有选择的建立一些中转站(投入成本),为一些 用户提供服务并获得收益(获益之和)。那么如何选择最终建立的中转站才能让 公司的净获利最大呢?(净获利 = 获益之和 – 投入成本之和)
输入描述 Input Description
输入文件中第一行有两个正整数 N 和 M 。 第二行中有 N 个整数描述每一个通讯中转站的建立成本,依次为 P1, P2, …, PN 。 以下 M 行,第(i + 2)行的三个数 Ai, Bi和 Ci描述第 i 个用户群的信息。 所有变量的含义可以参见题目描述。
输出描述 Output Description
你的程序只要向输出文件输出一个整数,表示公司可以得到的最大净获利。
样例输入 Sample Input
5 5
1 2 3 4 5
1 2 3
2 3 4
1 3 3
1 4 2
4 5 3
样例输出 Sample Output
4
数据范围及提示 Data Size & Hint
选择建立 1、2、3 号中转站,则需要投入成本 6,获利为 10,因此得到最大 收益 4。
80%的数据中:N≤200,M≤1 000。
100%的数据中:N≤5 000,M≤50 000,0≤Ci≤100,0≤Pi≤100。
仔细观察问题可以发现,对于获得某一用户群的价值必须建立关于用户群的两个基站,容易想到最大权闭合路
对于每个基站权值为负,而对于每个用户群权值为正,将超级源点与用户群相连,流量为价值,将超级基站与超级汇点相连,流量同样为价值,做超级源点到超级汇点的最大流即可,对于关于最大权闭合图中最优性证明可以去网上参考有关资料;
#include<cstdio>#include<climits>#include<cstring>#include<vector>#include<queue>#include<iostream>using namespace std;#define N 5005#define M 50002#define INF INT_MAX/3*2struct NetWork{ struct Edge{ int fr,to,cap,flow; }; vector<Edge> edge;vector<int> g[M+N]; bool b[N+M];int d[N+M],p[N+M],cur[N+M]; int n,m,flow,S,T,ans; void in(int &x){ x=0;char ch=getchar(); while(ch>'9'||ch<'0') ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return; } void Add_Edge(int fr,int to,int cap,int flow){ edge.push_back(Edge{fr,to,cap,flow}); edge.push_back(Edge{to,fr,0,0}); int t=edge.size(); g[fr].push_back(t-2);g[to].push_back(t-1); } void init(){ in(n),in(m);S=0,T=n+m+1;int x,y,z; for(int i=1;i<=n;i++){ in(x);Add_Edge(i,T,x,0); } for(int i=1;i<=m;i++){ in(x);in(y);in(z); Add_Edge(S,n+i,z,0);Add_Edge(n+i,x,INF,0);Add_Edge(n+i,y,INF,0); ans+=z; } } bool bfs(){ memset(b,0,sizeof(b));memset(d,-1,sizeof(d)); queue<int> q;int x; d[S]=0;b[S]=true;q.push(S); while(!q.empty()){ x=q.front();q.pop(); for(int i=0;i<g[x].size();i++){ Edge &e=edge[g[x][i]]; if(!b[e.to]&&e.cap>e.flow){ b[e.to]=true;d[e.to]=d[x]+1;q.push(e.to); } } } return b[T]; } void MaxFlow(){ int k,x,mine,minf; while(bfs()){ memset(cur,0,sizeof(cur));k=0;x=S; for(;;){ if(x==T){ mine=-1;minf=INF; for(int i=0;i<k;i++){ Edge &e=edge[p[i]]; if(e.cap-e.flow<minf){ minf=e.cap-e.flow;mine=i; } } for(int i=0;i<k;i++){ edge[p[i]].flow+=minf; edge[p[i]^1].flow-=minf; } flow+=minf;x=edge[p[mine]].fr;k=mine; } for(int &i=cur[x];i<g[x].size();i++){ Edge &e=edge[g[x][i]]; if(e.cap>e.flow&&d[x]+1==d[e.to]) break; } if(cur[x]<g[x].size()){ p[k++]=g[x][cur[x]];x=edge[g[x][cur[x]]].to; } else{ if(!k) break; d[x]=-1;k--;x=edge[p[k]].fr; } } } } void solve(){ init();MaxFlow();printf("%d",ans-flow); }}s;int main(){ s.solve();return 0;}
- BZOJ_P1497&Codevs_P1789 最大获利(最大权闭合图最小割最大流)
- 最大权闭合图 BZOJ 1497 最大获利 (最小割)
- 【NOI2006】最大获利 最大权闭合图+最小割
- [NOI2006]最大获利(最大权闭合图 最小割应用)
- bzoj1497: [NOI2006]最大获利(最大权闭合子图,最小割)
- 最小割模型——最大权闭合子图 【NOI2006】bzoj1497 最大获利
- [最大权闭合子图 & 最小割] BZOJ1497: [NOI2006] 最大获利
- bzoj1497 [NOI2006]最大获利(最大权闭合图,最小割)
- POJ 2987 最大流最小割最大权闭合图
- bzoj1497 最大获利 最大权闭合图
- NOI2006 最大获利 (最大权闭合图)
- [NOI2006] 最大获利 (最大权闭合图)
- noi 2006 最大收益 最大权闭合图转最小割转最大流
- NOI 2006 最大获利(最大权闭合)
- poj 2987 最大权闭合图 最大流最小割模板
- [NOI 2006]最大获利(最大权闭合图)
- Hdu3879 Base Station 最大权闭合子图 最大获利
- NOI2006——最大获利(最大权闭合图)
- Linux下USB驱动框架分析
- java内存管理
- Android使用系统自带的audioreorder和mediaplayer进行录音和播放,外加进度条的滚动!
- Linux命令--mtr----traceroute+ping
- Android样式之Shape
- BZOJ_P1497&Codevs_P1789 最大获利(最大权闭合图最小割最大流)
- 设计模式-单例
- 不可不知的:iOS开发的22个诡异技巧
- matlab2012 toolbox 曲线拟合
- Python学习手册 - 05
- Cygwin完全下载指南
- (实训第二天)内核空间与用户空间
- 23种设计模式
- 刷新界面之invalidate()与postInvalidate()