【NOI2006】 最大获利

题目描述
最大获利
【问题描述】
新的技术正冲击着手机通讯市场,对于各大运营商来说,这既是机遇,更是
挑战。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
【样例说明】
选择建立 123 号中转站,则需要投入成本 6,获利为 10,因此得到最大
收益 4。
【评分方法】
本题没有部分分,你的程序的输出只有和我们的答案完全一致才能获得满
分,否则不得分。
【数据规模和约定】
80%的数据中:N≤200,M≤1 000100%的数据中: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.
posted @ 2012-06-02 22:12  datam  阅读(324)  评论(0编辑  收藏  举报