码迷,mamicode.com
首页 > 其他好文 > 详细

CodeVS 1789 最大获利

时间:2014-10-27 12:19:11      阅读:309      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   color   io   os   ar   使用   

1789 最大获利

 

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。 

 

解题:最大权闭合子图

bubuko.com,布布扣
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <climits>
 7 #include <vector>
 8 #include <queue>
 9 #include <cstdlib>
10 #include <string>
11 #include <set>
12 #include <stack>
13 #define LL long long
14 #define pii pair<int,int>
15 #define INF 0x3f3f3f3f
16 using namespace std;
17 const int maxn = 60000;
18 struct arc{
19     int to,flow,next;
20     arc(int x = 0,int y = 0,int z = -1){
21         to = x;
22         flow = y;
23         next = z;
24     }
25 };
26 arc e[1000000];
27 int head[maxn],d[maxn],cur[maxn];
28 int tot,S,T,n,m;
29 void add(int u,int v,int flow){
30     e[tot] = arc(v,flow,head[u]);
31     head[u] = tot++;
32     e[tot] = arc(u,0,head[v]);
33     head[v] = tot++;
34 }
35 bool bfs(){
36     memset(d,-1,sizeof(d));
37     d[S] = 1;
38     queue<int>q;
39     q.push(S);
40     while(!q.empty()){
41         int u = q.front();
42         q.pop();
43         for(int i = head[u]; ~i; i = e[i].next){
44             if(e[i].flow && d[e[i].to] == -1){
45                 d[e[i].to] = d[u] + 1;
46                 q.push(e[i].to);
47             }
48         }
49     }
50     return d[T] > -1;
51 }
52 int dfs(int u,int low){
53     if(u == T) return low;
54     int tmp = 0,a;
55     for(int &i = cur[u]; ~i; i = e[i].next){
56         if(e[i].flow && d[e[i].to] == d[u] + 1&&(a=dfs(e[i].to,min(low,e[i].flow)))){
57             e[i].flow -= a;
58             e[i^1].flow += a;
59             tmp += a;
60             low -= a;
61             if(!low) break;
62         }
63     }
64     if(!tmp) d[u] = -1;
65     return tmp;
66 }
67 int dinic(){
68     int ans = 0;
69     while(bfs()){
70         memcpy(cur,head,sizeof(head));
71         ans += dfs(S,INF);
72     }
73     return ans;
74 }
75 int main() {
76     int u,v,w;
77     while(~scanf("%d %d",&n,&m)){
78         memset(head,-1,sizeof(head));
79         S = tot = 0;
80         T = n + m + 1;
81         int ans = 0;
82         for(int i = 1; i <= n; ++i){
83             scanf("%d",&w);
84             add(i,T,w);
85         }
86         for(int i = 0; i < m; ++i){
87             scanf("%d %d %d",&u,&v,&w);
88             add(n+i+1,u,INF);
89             add(n+i+1,v,INF);
90             add(S,n+i+1,w);
91             ans += w;
92         }
93         printf("%d\n",ans - dinic());
94     }
95     return 0;
96 }
View Code

 

CodeVS 1789 最大获利

标签:des   style   blog   http   color   io   os   ar   使用   

原文地址:http://www.cnblogs.com/crackpotisback/p/4053656.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!