洛谷P1361 小M的作物 最小割建模

2021-08-31 03:16:56 字數 1394 閱讀 7504

題目大意

有n株植物,a,b兩塊田地,每株植物i,種在a田,可以獲得a[i]的收益,種在b田,可以獲得b[i]的收益。此外還存在m種額外收益,其中第i中額外收益可以這樣描述:如果集合u[i]中的所有植物全部種在a田,那麼可以獲得exa[i]的額外收益,如果集合u[i]中的所有植物全部種在b田,那麼可以獲得exb[i]的額外收益,如果並沒有全部種在同一塊田裡,沒有任何額外收益。

請你合理安排種植方案,求出最大收益。

解題思路

這是經典的最小割模型。我們將源點s當成a田,匯點t當成b田,每株植物抽象成乙個點(編號1~n),分別連有向邊(s,i,a[i])、(i,t,b[i]),這樣,由於最小割中要使得s不能到達t,所以這兩邊至少要割去一邊,我們就實現了第一種代價的取捨。

可是第二步呢?我們考慮構建額外點。對於第i種額外收益,我們建兩個額外點a_i,b_i,新增有向邊(s,a_i,exa[i])、(b_i,t,exb[i]),然後對於u[i]中的每乙個點x,連這樣的有向邊:(a_i,x,∞)、(x,b_i,∞),這樣,如果所有作物都在一塊田地,相應的收益邊就得以保留,否則必須割去,這樣就體現了第二種收益。

對這樣乙個圖跑一邊最大流,也就得到了最小割,也就得到了最少需要捨棄的收益,直接用收益總和sum減去最小割mincut即可得到最大收益。

本題邊數達到百萬級別,推薦sap**!!(所以說網路流到底可以跑多快啊,完全看不出極限啊……)

p.s.一開始建圖的時候標號搞錯了,調了n久,還以為sap寫萎了……看來網路流題如果發現答案不對,最好優先檢查建圖!

#include #include #define rep(i,j,k) for (i=j;i<=k;i++)

using namespace std;

const int n=5e3+5,m=4e6+5000,inf=2e9;

int en,fst[n],nxt[m],to[m],cap[m];

int n,m,i,x,k,a,b,tot,ans,s[n];

int maxflow,flow,found,h[n],hn[n];

void create(int u,int v,int c)

void add(int u,int v,int c)

void sap(int x)

for (j=fst[x];j;j=nxt[j])

if (cap[j]>0)

min=min(min,h[v]);

} if (found)

else

}int main()

hn[0]=tot+1;

while (h[0]<=tot)

ans-=maxflow;

printf("%d\n",ans);

return 0;}/*

0~tot

*/

P1361 小M的作物 最小割

小m在mc裡開闢了兩塊巨大的耕地a和b 你可以認為容量是無窮 現在,小p有n中作物的種子,每種作物的種子有1個 就是可以種一棵作物 用1.n編號 現在,第i種作物種植在a中種植可以獲得ai的收益,在b中種植可以獲得bi的收益,而且,現在還有這麼一種神奇的現象,就是某些作物共同種在一塊耕地中可以獲得額...

最小割 P1361 小M的作物

p1361 小m的作物 建圖好題。思路 看得出來還是經典的兩者取一模型,也就是找出一種割邊方式,將點劃分為兩個集合,且割邊花費最小。但是給出的是收益而非費用,怎麼辦呢?最大收益 總收益 最小損失。總收益就是把題目給出的種a地種b地的收益以及組合的bonus全部加起來。最小損失就是跑最大流 最小割 將...

洛谷 P1361 小M的作物 最大流最小割

題目大意 給出 n 個植物,每個植物種在 a 農場的收益是 a i 種在 b 農場的收益是 b i 再給出 m 組關係,每組中的所有植物如果都在 a 農場的話額外收益為 c1 如果同時在 b 農場的話額外收益為 c2,問如何種植可以使得收益最大 題目分析 每種植物的兩種選擇可以視為兩個集合,對於選擇...