[NOI2006]最大獲利__網路流

來源:互聯網
上載者:User

Description

新的技術正衝擊著手機通訊市場,對於各大電訊廠商來說,這既是機遇,更是挑戰。THU集團旗下的CS&T通訊公司在新一代通訊技術血戰的前夜,需要做太多的準備工作,僅就站址選擇一項,就需要完成前期市場研究、站址勘測、最佳化等項目。在前期市場調查和站址勘測之後,公司得到了一共N個可以作為通訊訊號中轉站的地址,而由於這些地址的地理位置差異,在不同的地方建造通訊中轉站需要投入的成本也是不一樣的,所幸在前期調查之後這些都是已知資料:建立第i個通訊中轉站需要的成本為Pi(1≤i≤N)。另外公司調查得出了所有期望中的使用者群,一共M個。關於第i個使用者群的資訊概括為Ai, Bi和Ci:這些使用者會使用中轉站Ai和中轉站Bi進行通訊,公司可以獲益Ci。(1≤i≤M, 1≤Ai, Bi≤N) THU集團的CS&T公司可以有選擇的建立一些中轉站(投入成本),為一些使用者提供服務並獲得收益(獲益之和)。那麼如何選擇最終建立的中轉站才能讓公司的淨獲利最大呢。(淨獲利 = 獲益之和 - 投入成本之和)

Input

輸入檔案中第一行有兩個正整數N和M 。第二行中有N個整數描述每一個通訊中轉站的建立成本,依次為P1, P2, …, PN 。以下M行,第(i + 2)行的三個數Ai, Bi和Ci描述第i個使用者群的資訊。所有變數的含義可以參見題目描述。

Output

你的程式只要向輸出檔案輸出一個整數,表示公司可以得到的最大淨獲利。

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

HINT

【範例說明】選擇建立1、2、3號中轉站,則需要投入成本6,獲利為10,因此得到最大收益4。【評分方法】本題沒有部分分,你的程式的輸出只有和我們的答案完全一致才能獲得滿分,否則不得分。【資料規模和約定】 80%的資料中:N≤200,M≤1 000。 100%的資料中:N≤5 000,M≤50 000,0≤Ci≤100,0≤Pi≤100。

題解
最大閉合權子圖,源點向每個使用者連邊,流量為獲利值,使用者向所需機器連邊,流量無限,機器向匯點連邊,流量為代價,答案為總獲利減最小割。

代碼

#include<bits/stdc++.h>#define inf 0x7fffffff#define N 150005#define M 1000005#define ll long longusing namespace std;inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}int Head[N],ret[M],Next[M],len[M],gap[N];int dis[N],n,m,S,T,tot,cur[N],ans,sum;inline void ins(int u,int v,int w){    ret[++tot]=v;len[tot]=w;    Next[tot]=Head[u];Head[u]=tot;}bool bfs(){    for (int i=1;i<=T;i++) dis[i]=-1;queue<int>q;    q.push(S);dis[S]=0;    while (!q.empty())    {        int now=q.front();q.pop();        for (int i=Head[now];i;i=Next[i])            if (dis[ret[i]]==-1&&len[i])            {                dis[ret[i]]=dis[now]+1;                q.push(ret[i]);            }    }    if (dis[T]==-1) return 0;return 1;}int dfs(int u,int aug){    if (u==T||aug==0) return aug;    int flow=0;    for (int i=cur[u];i;i=Next[i])        if (dis[ret[i]]==dis[u]+1)        {            int t=dfs(ret[i],min(aug-flow,len[i]));            len[i]-=t;len[i^1]+=t;flow+=t;            if(len[i])cur[u]=i;            if (flow==aug) return flow;        }    if (flow==0) dis[u]=-1;    return flow;}void dinic(){    while (bfs())    {        for (int i=1;i<=T;i++) cur[i]=Head[i];        ans+=dfs(S,inf);    }}int isap(int u,int aug){    if (u==T||aug==0) return aug;    int min_d=T,flow=0;    for (int i=Head[u];i;i=Next[i])    {        if (len[i]>0)        {            if (dis[ret[i]]+1==dis[u])            {                int t=isap(ret[i],min(aug-flow,len[i]));                len[i]-=t;len[i^1]+=t;flow+=t;            }            if (flow==aug) return flow;            if (dis[S]==T) return flow;            min_d=min(min_d,dis[ret[i]]+1);        }    }    if (flow==0)    {        gap[dis[u]]--;        if (gap[dis[u]]==0) dis[S]=T;        dis[u]=min_d;        gap[dis[u]]++;    }    return flow;}int main(){    n=read();m=read();S=n+m+1;T=S+1;tot=1;    for (int i=1;i<=n;i++)    {        int w=read();        ins(i+m,T,w);ins(T,i+m,0);    }    for (int i=1;i<=m;i++)    {        int a=read(),b=read(),c=read();        sum+=c;        ins(S,i,c);ins(i,S,0);        ins(i,a+m,inf);ins(a+m,i,0);        ins(i,b+m,inf);ins(b+m,i,0);    }    //dinic();    while (dis[S]!=T)    {        ans+=isap(S,inf);    }    printf("%d",sum-ans);    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.