hdu 3987 Base Station 最大获利+最大权闭合图

本文深入探讨了大数据开发的关键技术和实际应用,包括Hadoop、Spark、Flink等主流框架的使用,以及数据处理、存储、分析等核心流程。通过丰富的案例分析,读者将掌握大数据项目实施的全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 P i (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 A i, B i and C i, which means if place A i and B i can communicate with each other, the company will get C i 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, A i, B i and C i, 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

 

 //

 

新建一个源点S,S与每个通讯线路的点相连,边权为收益

新建一个汇点T,T与每个通讯站相连,边权为建造费用

通讯线路->通讯站之间的边权为无穷大

最后的结果为所有通讯线路总的收益-最小割

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=55010;
const int M=950000;
const int inf=(1<<28);
int head[N];
struct Edge
{
    int v,next,w;
} edge[M];
int cnt,n,s,t;//n从0开始  0->n-1
void addedge(int u,int v,int w)
{
    edge[cnt].v=v;
    edge[cnt].w=w;
    edge[cnt].next=head[u];
    head[u]=cnt++;
    edge[cnt].v=u;
    edge[cnt].w=0;
    edge[cnt].next=head[v];
    head[v]=cnt++;
}
int sap()
{
    int pre[N],cur[N],dis[N],gap[N];
    int flow=0,aug=inf,u;
    bool flag;
    for(int i=0; i<n; i++)
    {
        cur[i]=head[i];
        gap[i]=dis[i]=0;
    }
    gap[s]=n;
    u=pre[s]=s;
    while(dis[s]<n)
    {
        flag=0;
        for(int &j=cur[u]; j!=-1; j=edge[j].next)
        {
            int v=edge[j].v;
            if(edge[j].w>0&&dis[u]==dis[v]+1)
            {
                flag=1;
                if(edge[j].w<aug) aug=edge[j].w;
                pre[v]=u;
                u=v;
                if(u==t)
                {
                    flow+=aug;
                    while(u!=s)
                    {
                        u=pre[u];
                        edge[cur[u]].w-=aug;
                        edge[cur[u]^1].w+=aug;
                    }
                    aug=inf;
                }
                break;
            }
        }
        if(flag) continue;
        int mindis=n;
        for(int j=head[u]; j!=-1; j=edge[j].next)
        {
            int v=edge[j].v;
            if(edge[j].w>0&&dis[v]<mindis)
            {
                mindis=dis[v];
                cur[u]=j;
            }
        }
        if((--gap[dis[u]])==0)
            break;
        gap[dis[u]=mindis+1]++;
        u=pre[u];
    }
    return flow;
}

//初始化  cnt=0;memset(head,-1,sizeof(head));

int main()
{
    int m,p;
    while(scanf("%d%d",&m,&p)==2)
    {
        cnt=0;
        memset(head,-1,sizeof(head));
        n=m+p+2;
        s=0,t=n-1;
        int sum=0;
        for(int i=1;i<=m;i++)
        {
            int cost;scanf("%d",&cost);
            addedge(i,t,cost);
        }
        for(int i=1;i<=p;i++)
        {
            int u,v,w;scanf("%d%d%d",&u,&v,&w);
            int h=m+i;
            sum+=w;
            addedge(s,h,w);
            addedge(h,u,inf);
            addedge(h,v,inf);
        }
        printf("%d\n",sum-sap());
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值