Base Station
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 65768/32768 K (Java/Others)Total Submission(s): 1540 Accepted Submission(s): 639
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.
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.
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题意:通讯公司要建立若干个基站,有n个地点可以建立,建立了基站的地点可以互相通信。在每个地点建立基站会有相应的花费。另外给出m对地点,每对地点a b c表示若a和b能通信,那么将会获得c的收益。现在要求出建立基站能获得的最大收益。思路:求最大权闭合图。将每个地点建基站的花费看成负权,收益看成正权,那么要求的是 正权总和 - 最小割容量总和。构图如下:每个基站看成一个点,连一条边到汇点,容量为相应的花费。将每对有收益的地点a和b的关系看成点,源点连一条边到该点,容量为收益,然后该点连一条边到a、b,容量为INF(表示选了这个点那么一定要选关联的两个点)。这样,最后选取方案付出的代价为min(建造a和b 的花费,同时建a和b时得到的收益)。最后总正权-最大流即为所求AC代码:#include <iostream> #include <cmath> #include <cstdlib> #include <cstring> #include <cstdio> #include <queue> #include <ctime> #include <algorithm> #define ll __int64 using namespace std; const int INF = 1000000000; const int maxn = 60000; struct Edge{ int u, v, cap, flow, next; }et[500000]; int low[maxn], dis[maxn], cnt[maxn], pre[maxn], cur[maxn], eh[maxn]; int n, m, s, t, num; void init(){ memset(eh, -1, sizeof(eh)); num = 0; } void add(int u, int v, int cap, int flow){ Edge e = {u, v, cap, flow, eh[u]}; et[num] = e; eh[u] = num++; } void addedge(int u, int v, int cap){ add(u, v, cap, 0); add(v, u, 0, 0); } int isap(int s, int t, int nv){ int u, v, now, flow = 0; memset(low, 0, sizeof(low)); memset(cnt, 0, sizeof(cnt)); memset(dis, 0, sizeof(dis)); for(u = 0; u <= nv; u++) cur[u] = eh[u]; low[s] = INF, cnt[0] = nv, u = s; while(dis[s] < nv) { for(now = cur[u]; now != -1; now = et[now].next) if(et[now].cap - et[now].flow && dis[u] == dis[v = et[now].v] + 1) break; if(now != -1) { cur[u] = pre[v] = now; low[v] = min(et[now].cap - et[now].flow, low[u]); u = v; if(u == t) { for(; u != s; u = et[pre[u]].u) { et[pre[u]].flow += low[t]; et[pre[u]^1].flow -= low[t]; } flow += low[t]; low[s] = INF; } } else { if(--cnt[dis[u]] == 0) break; dis[u] = nv, cur[u] = eh[u]; for(now = eh[u]; now != -1; now = et[now].next) if(et[now].cap - et[now].flow && dis[u] > dis[et[now].v] + 1) dis[u] = dis[et[now].v] + 1; cnt[dis[u]]++; if(u != s) u = et[pre[u]].u; } } return flow; } int main() { int cost, a, b, c; while(~scanf("%d%d", &n, &m)) { init(); s = 0; t = n + m + 1; for(int i = 1; i <= n; i++) { scanf("%d", &cost); addedge(i, t, cost); } int sum = 0; for(int i = 1; i <= m; i++) { scanf("%d%d%d", &a, &b, &c); sum += c; addedge(s, i + n, c); addedge(i + n, a, INF); addedge(i + n, b, INF); } printf("%d\n", sum - isap(s, t, t + 1)); } return 0; }