最大获利
Posted kakakakakaka
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大获利相关的知识,希望对你有一定的参考价值。
最大获利
时间限制: 1 Sec 内存限制: 128 MB题目描述
新的技术正冲击着手机通讯市场,对于各大运营商来说,这既是机遇,更是挑战。 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 公司可以有选择的建立一些中转站(投入成本),为一些用户提供服务并获得收益(获益之和)。那么如何选择最终建立的中转站才能让公司的净获利最大呢?(净获利 = 获益之和 – 投入成本之和)
输入
输入中第一行有两个正整数N 和M 。
第二行中有 N 个整数描述每一个通讯中转站的建立成本,依次为P1, P2, …, PN 。
以下 M 行,第(i + 2)行的三个数 Ai, Bi 和 Ci 描述第 i 个用户群的信息。
所有变量的含义可以参见题目描述。
输出
你的程序只要输出一个整数,表示公司可以得到的最大净获利。
样例输入
样例输出
提示
原题要求:
只需要向输出文件输出一行,行内不得有多余空白字符,行末须有一个换行/回车符,格式不对不能得分。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<cstdlib> #include<queue> #include<stack> #include<ctime> #include<vector> using namespace std; int n,m; struct node { int next,to,cap; }edge[500001]; int head[200001],size=1; void putin(int from,int to,int cap) { size++; edge[size].next=head[from]; edge[size].to=to; edge[size].cap=cap; head[from]=size; } void in(int from,int to,int cap) { putin(from,to,cap); putin(to,from,0); } int dist[200001],numbs[200001]; void bfs(int src,int des) { int i; queue<int>mem; mem.push(des); dist[des]=0;numbs[0]++; while(!mem.empty()) { int x=mem.front();mem.pop(); for(i=head[x];i!=-1;i=edge[i].next) { int y=edge[i].to; if(edge[i].cap==0&&dist[y]==0&&y!=des) { dist[y]=dist[x]+1; numbs[dist[y]]++; mem.push(y); } } } return; } int dfs(int src,int flow,int des) { if(src==des)return flow; int i,low=0,mindist=n+m+2; for(i=head[src];i!=-1;i=edge[i].next) { int y=edge[i].to; if(edge[i].cap) { if(dist[y]==dist[src]-1) { int t=dfs(y,min(flow-low,edge[i].cap),des); edge[i].cap-=t; edge[i^1].cap+=t; low+=t; if(dist[src]>=n+m+2)return low; if(low==flow)break; } mindist=min(mindist,dist[y]+1); } } if(!low) { if(!(--numbs[dist[src]]))dist[0]=n+m+2; ++numbs[dist[src]=mindist]; } return low; } int ISAP(int src,int des) { int ans=0; bfs(src,des); while(dist[0]<n+m+2)ans+=dfs(src,2e8,des); return ans; } int cnt; int main() { //freopen("4.in","r",stdin); int i,j; memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); for(i=1;i<=n;i++) { scanf("%d",&j); in(m+i,m+n+1,j); } for(i=1;i<=m;i++) { int a,b,dis; scanf("%d%d%d",&a,&b,&dis); in(i,m+a,2e8); in(i,m+b,2e8); in(0,i,dis); cnt+=dis; } int maxflow=ISAP(0,n+m+1); printf("%d",cnt-maxflow); }
以上是关于最大获利的主要内容,如果未能解决你的问题,请参考以下文章