题目描述
最大获利 【问题描述】 新的技术正冲击着手机通讯市场,对于各大运营商来说,这既是机遇,更是 挑战。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 个用户群的信息。 所有变量的含义可以参见题目描述。 【输出格式】 你的程序只要向输出文件输出一个整数,表示公司可以得到的最大净获利。 【输入样例】 55 12345 123 234 133 142 453 【输出样例】 4 【样例说明】 选择建立 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。
flow
1 (* 2 *Problem: NOI2006 最大获利 3 *Author : Chen Yang 4 *Time : 2012.6.2 8:00 am 5 *State : Solved 6 *Memo : 网络流、最大流最小割 7 *) 8 program profit; 9 const maxn=60000; 10 max=100000000; 11 type 12 ty1=^ty2; 13 ty2=record 14 x,f:longint; 15 next,up:ty1; 16 end; 17 18 var 19 n,m,i,x,y,z,s,t,tot,ans:longint; 20 first:array[0..maxn] of ty1; 21 d,vd:array[0..maxn] of longint; 22 //======================= 23 function min(a,b:longint):longint; inline; 24 begin if a<b then exit(a) else exit(b); end; 25 //======================= 26 procedure insert(x,y,z:longint); inline; 27 var 28 p,q:ty1; 29 begin 30 new(p); 31 p^.x:=y; p^.f:=z; 32 p^.next:=first[x]; first[x]:=p; 33 new(q); 34 q^.x:=x; q^.f:=0; 35 q^.next:=first[y]; first[y]:=q; 36 q^.up:=p; p^.up:=q; 37 end; 38 //======================= 39 function sap(x,flow:longint):longint; 40 var 41 p:ty1; 42 tmp:longint; 43 begin 44 if x=t then exit(flow); 45 sap:=0; 46 p:=first[x]; 47 while p<>nil do 48 begin 49 if (p^.f>0)and(d[p^.x]+1=d[x]) then 50 begin 51 tmp:=sap(p^.x,min(flow-sap,p^.f)); 52 dec(p^.f,tmp); 53 inc(p^.up^.f,tmp); 54 inc(sap,tmp); 55 if sap=flow then exit; 56 end; 57 p:=p^.next; 58 end; 59 if d[s]=tot then exit; 60 dec(vd[d[x]]); 61 if vd[d[x]]=0 then d[s]:=tot; 62 inc(d[x]); inc(vd[d[x]]); 63 end; 64 //======================= 65 begin 66 assign(input,'profit.in'); reset(input); 67 assign(output,'profit.out'); rewrite(output); 68 read(n,m); s:=0; t:=n+m+1; 69 for i:=1 to n do 70 begin 71 read(x); insert(s,i,x); 72 end; 73 for i:=n+1 to n+m do 74 begin 75 read(x,y,z); 76 insert(x,i,max); insert(y,i,max); 77 insert(i,t,z); inc(ans,z); 78 end; 79 tot:=n+m+2; vd[0]:=tot; 80 while d[s]<tot do dec(ans,sap(s,maxlongint)); 81 writeln(ans); 82 close(input); close(output); 83 end.