Base Station
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 65768/32768 K (Java/Others)
Total Submission(s): 1983 Accepted Submission(s): 838
Problem Description
A famous mobile communication company is planning to build a new set of base stations. According to the previous investigation, n places are chosen as the possible new locations to build those new stations. However, the condition of each position varies much,
so the costs to built a station at different places are different. The cost to build a new station at the ith place is Pi (1<=i<=n).
When complete building, two places which both have stations can communicate with each other.
Besides, according to the marketing department, the company has received m requirements. The ith requirement is represented by three integers Ai, Bi and Ci, which means if place Ai and Bi can communicate
with each other, the company will get Ci profit.
Now, the company wants to maximize the profits, so maybe just part of the possible locations will be chosen to build new stations. The boss wants to know the maximum profits.
Input
Multiple test cases (no more than 20), for each test case:
The first line has two integers n (0<n<=5000) and m (0<m<=50000).
The second line has n integers, P1 through Pn, describes the cost of each location.
Next m line, each line contains three integers, Ai, Bi and Ci, describes the ith requirement.
Output
One integer each case, the maximum profit of the company.
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
Author
liulibo
Source
2011 Multi-University Training Contest 5 - Host
by BNU
Recommend
lcy | We have carefully selected several similar problems for you: 3657 1565 3491 3887 3889
题意:有n个地方可供建造基站,建造每个基站有一个成本p,有m个用户群,第i个用户群的用户会使用基站ai和bi进行通讯,公司获利ci,公司有选择的修建基站,问最大的净利润为多少。净利润=总收益-总成本。
思路:首先分析题目中的决策因素。在满足了第i个用户群后,便可以得到收益,然而满足第 个用户群需要有必要条件:建立中转站ai和中转站bi,同时要花去相应费用。留心这个所谓 的必要条件,便可联想到闭合图的性质。分析后发现,本题就是最大权闭合图的一个特例。把它抽象成这样一个有向图模型:每个用户群i作为一个结点分别向相应的中转站ai和中转站bi 连有向边。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <string> #include <map> #include <stack> #include <vector> #include <set> #include <queue> #pragma comment (linker,"/STACK:102400000,102400000") #define maxn 55005 #define MAXM 555005 #define mod 1000000009 #define INF 0x3f3f3f3f #define pi acos(-1.0) #define eps 1e-6 #define lson rt<<1,l,mid #define rson rt<<1|1,mid+1,r #define FRE(i,a,b) for(i = a; i <= b; i++) #define FREE(i,a,b) for(i = a; i >= b; i--) #define FRL(i,a,b) for(i = a; i < b; i++) #define FRLL(i,a,b) for(i = a; i > b; i--) #define mem(t, v) memset ((t) , v, sizeof(t)) #define sf(n) scanf("%d", &n) #define sff(a,b) scanf("%d %d", &a, &b) #define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c) #define pf printf #define DBG pf("Hi\n") typedef long long ll; using namespace std; struct Edge { int u,v,cap,next; }edge[MAXM]; int head[maxn],cur[maxn],level[maxn]; int num,n,m; void init() { num=0; mem(head,-1); } void addedge(int u,int v,int w) { edge[num].u=u; edge[num].v=v; edge[num].cap=w; edge[num].next=head[u]; head[u]=num++; edge[num].u=v; edge[num].v=u; edge[num].cap=0; edge[num].next=head[v]; head[v]=num++; } bool bfs(int s,int t) { mem(level,-1); queue<int>Q; level[s]=0; Q.push(s); while (!Q.empty()) { int u=Q.front();Q.pop(); for (int i=head[u];i+1;i=edge[i].next) { int v=edge[i].v; if (edge[i].cap>0&&level[v]==-1) { level[v]=level[u]+1; Q.push(v); } } } return level[t]!=-1; } int dfs(int u,int t,int f) { if (u==t) return f; for (int &i=cur[u];i+1;i=edge[i].next) { int v=edge[i].v; if (edge[i].cap>0&&level[v]==level[u]+1) { int d=dfs(v,t,min(f,edge[i].cap)); if (d>0) { edge[i].cap-=d; edge[i^1].cap+=d; return d; } } } return 0; } int dinic(int s,int t,int nodenum) { int flow=0; while (bfs(s,t)) { for (int i=0;i<nodenum+1;i++) cur[i]=head[i]; int f; while ((f=dfs(s,t,INF))>0) flow+=f; } return flow; } int main() { // freopen("C:/Users/asus1/Desktop/IN.txt","r",stdin); int i,j,u,v,w; while (~sff(n,m)) { int sum=0; init(); for (i=1;i<=n;i++) { scanf("%d",&w); addedge(m+i,n+m+1,w); } for (i=1;i<=m;i++) { sfff(u,v,w); sum+=w; addedge(0,i,w); addedge(i,u+m,INF); addedge(i,v+m,INF); } printf("%d\n",sum-dinic(0,n+m+1,n+m+2)); } return 0; }