bzoj1497 NOI2006 最大獲利

2022-05-01 06:30:11 字數 2783 閱讀 6379

time limit: 5 sec  memory limit: 64 mb

submit: 6241  solved: 3006

[submit][status][discuss]

新的技術正衝擊著手機通訊市場,對於各大運營商來說,這既是機遇,更是挑戰。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公司可以有選擇的建立一些中轉站(投入成本),為一些使用者提供服務並獲得收益(獲益之和)。那麼如何選擇最終建立的中轉站才能讓公司的淨獲利最大呢?(淨獲利 = 獲益之和 - 投入成本之和)

輸入檔案中第一行有兩個正整數n和m 。第二行中有n個整數描述每乙個通訊中轉站的建立成本,依次為p1, p2, …, pn 。以下m行,第(i + 2)行的三個數ai, bi和ci描述第i個使用者群的資訊。所有變數的含義可以參見題目描述。

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

5 51 2 3 4 5

1 2 3

2 3 4

1 3 3

1 4 2

4 5 3

4【樣例說明】選擇建立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。

分析:最大權閉合子圖模型.

利用網路流求解. 對於每乙個中轉站,向匯點連邊,邊權為建中轉站的費用.  對於每乙個使用者群,源點向其連邊,費用為收益. 每乙個使用者群向其所依賴的兩個中轉站連邊,費用為inf.

考慮最小割的意義:使用者群與中轉站之間的邊肯定是不能割的. 如果割掉源點與使用者群的邊,就表示這個使用者群的方案不會被選擇. 如果割掉中轉站與匯點的連邊,就表示這個中轉站會被選擇. 最小割實際上就是額外的花費. 

答案就是所有使用者群的收益-最小割.

最大流問題可以轉換成最小割問題求解,當最小割的意義明確的時候.  在最小割問題中,如果不允許割掉某條邊,就將這條邊的邊權設為inf.這條邊所連的兩個點就會有乙個關聯. 挺巧妙的.

注意一點:算邊數要把反向邊也給算進來,陣列不要開小了!

#include #include 

#include

#include

#include

using

namespace

std;

const

int maxn = 60100,inf = 0x7fffffff

;int n,m,a[maxn],head[maxn],nextt[maxn * 6],w[maxn * 6],to[maxn * 6],tot = 2

,s,t;

intd[maxn],ans;

void add(int x,int y,int

z)bool

bfs()}}

return

false;}

int dfs(int u,int

f) }

if (res == 0

) d[u] = -1

;

return

res;

}void

dinic()

intmain()

for (int i = 1; i <= m; i++)

dinic();

printf(

"%d\n

",ans);

return0;

}

update:加了當前弧優化,快了好多.

#include #include 

#include

#include

#include

using

namespace

std;

const

int maxn = 60100,inf = 0x7fffffff

;int n,m,a[maxn],head[maxn],nextt[maxn * 6],w[maxn * 6],to[maxn * 6],tot = 2

,s,t;

intd[maxn],ans,cur[maxn];

void add(int x,int y,int

z)bool

bfs()}}

return

false;}

int dfs(int u,int

f) }

if (res == 0

) d[u] = -1

;

return

res;

}void

dinic()

}int

main()

for (int i = 1; i <= m; i++)

dinic();

printf(

"%d\n

",ans);

return0;

}

BZOJ1497 NOI2006 最大獲利

什麼是最大權閉合子圖 先解釋一下有向圖的閉合圖 閉合圖內任意點的任意後繼也一定還在閉合圖中。物理意義 事物間依賴關係 乙個事件要發生,它需要的所有前提也都一定要發生。最大權閉合圖 點權之和最大的閉合圖 最大權閉合圖構圖方法 1.增加源s匯t 2.源s連線原圖的正權點,容量為相應點權 3.原圖的負權點...

bzoj 1497 NOI2006最大獲利

我對題意的理解 給出一堆公司和一堆使用者,我們買公司需要花錢,每個使用者會支付報酬當且僅當他所鍾愛的兩個公司我都買了,問最大獲利 最大權閉合子圖 好厲害的樣子 首先我們連邊最小割ans 答案就是sum ans 這個可以想,sum表示在不需要支出的情況下的獲利,現在我們需要支出,所以要跑一遍最小割。感...

bzoj1497 NOI2006 最大收益

最小割 思路比較簡單 點數看起來很多但是因為是類似二分圖的東西所以跑的比較快 源點對每個使用者連容量為收益的邊 使用者向中轉站連容量無窮大的邊 中轉站向匯點連容量為成本的邊 要麼割掉使用者帶來的收益 要麼割掉成本 include include include using namespace std...