HDU 3879 Base Station(最大权闭合图)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37943488/article/details/81867161

Base Station

Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 65768/32768 K (Java/Others)
Total Submission(s): 2929    Accepted Submission(s): 1259


 

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

 

题目大意:一个著名的公司要建基站,有n个地方可能会被建基站,在i地建立基站的花费是pi,当i地建好基站后,那么Ai和Bi就可以通信,能获得Ci的收益,问最大收益

最大权闭合图,对于那些可能会被建基站的点,我们就将它连到汇点,容量为建这个基站的花费,对于那些边,将i与Ai和Bi相连,容量为无穷,表示如果满足第i个请求,那么表示Ai和Bi有基站,用源点将每个i请求相连,容量为满足这个请求的花费

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int maxm=200010;
const int maxn=60010;
const int inf=0x3f3f3f3f;
struct Node
{
    int from;
    int to;
    int capa;
    int next;
}edge[maxm<<1];
int cnt;
int source,sink;
int head[maxn];
int dep[maxn];
bool vis[maxn];
void init()
{
    memset(head,-1,sizeof(head));
    cnt=0;
    return;
}
void add(int u,int v,int capa)
{
    edge[cnt].from=u;
    edge[cnt].to=v;
    edge[cnt].capa=capa;
    edge[cnt].next=head[u];
    head[u]=cnt++;
    edge[cnt].from=v;
    edge[cnt].to=u;
    edge[cnt].capa=0;
    edge[cnt].next=head[v];
    head[v]=cnt++;
    return;
}
bool bfs()
{
    queue<int> que;
    que.push(source);
    memset(dep,-1,sizeof(dep));
    dep[source]=0;
    while(!que.empty())
    {
        int node=que.front();
        que.pop();
        for(int i=head[node];~i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(edge[i].capa>0&&dep[v]==-1)
            {
                dep[v]=dep[node]+1;
                if(v==sink) return true;
                que.push(v);
            }
        }
    }
    return dep[sink]!=-1;
}
int dfs(int node,int minn)
{
    if(node==sink||minn==0)
    {
        return minn;
    }
    int r=0;
    for(int i=head[node];~i;i=edge[i].next)
    {
        int v=edge[i].to;
        if(edge[i].capa>0&&dep[v]==dep[node]+1)
        {
            int tmp=dfs(v,min(edge[i].capa,minn));
            if(tmp>0)
            {
                edge[i].capa-=tmp;
                edge[i^1].capa+=tmp;
                r+=tmp;
                minn-=tmp;
                if(!minn) break;
            }
        }
    }
    if(!r) dep[node]=-1;
    return r;
}
int dinic()
{
    int maxflow=0;
    while(bfs())
    {
        maxflow+=dfs(source,inf);
    }
    return maxflow;
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int n,m;
    while(~scanf("%d%d",&n,&m))
	{
		init();
		source=0;
		sink=n+m+1;
		for(int i=1;i<=n;i++)
		{
			int x;
			scanf("%d",&x);
			add(m+i,sink,x);
		}
		int sum=0;
		for(int i=1;i<=m;i++)
		{
			int u,v,w;
			scanf("%d%d%d",&u,&v,&w);
			sum+=w;
			add(source,i,w);
			add(i,u+m,inf);
			add(i,v+m,inf);
		}
		printf("%d\n",sum-dinic());
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37943488/article/details/81867161