Base Station (hdu 3879 最大權閉合圖),hdu3879
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 DescriptionA 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.
InputMultiple 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.
OutputOne integer each case, the maximum profit of the company.
Sample Input
5 51 2 3 4 51 2 32 3 41 3 31 4 24 5 3
Sample Output
4
Authorliulibo
Source2011 Multi-University Training Contest 5 - Host by BNU
Recommendlcy | 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;}