BZOJ3438 小M的作物(最小割)

2021-07-26 11:46:55 字數 1738 閱讀 1819

傳送門

更科學一點的是最大權閉合子圖

popoqqq的題解:

首先我們先把所有的元素都放在集合a中 獲得所有的a[i]和c1[i] 然後考強調內容慮最大權閉合子圖

乙個點如果不選就放在a集合中 選就放在b集合中

乙個點如果選 那麼就要扣除相應的ai並獲得相應的b[i] 於是每個點的權值為b[i]-a[i]

將所有的子集拆點變成兩個

乙個子集中的任意乙個元素選擇 那麼就要扣除相應的c1[i] 這個子集的權值為-c1[i] 從這個子集的所有點出發連一條到達這個點的邊

乙個子集中所有的元素都選擇 那麼就會獲得相應的c2[i] 這個子集的權值為c2[i] 從這個點出發向這個子集的所有點連一條邊

然後建圖跑最大流即可

關於最大權閉合子圖的講解**beginend:

現在有乙個有向圖,每個點有點權,點權可正可負。對於任意一條有向邊i和j,選擇了點i就必須選擇點j,你需要選擇一些點使得得到權值最大。

這個問題可以用網路流解決。

建圖方法:對於任意點i,如果i權值為正,s向i連容量為其權值的邊,否則i向t連容量為其權值的絕對值的邊。原圖所有邊容量為正無窮。則最大權=正權和-最大流。

如何證明呢?我們把最大流理解成最小割,那麼割掉的邊一定不可能是正無窮的邊。

我們發現,選擇乙個正權點即不割掉s到其的邊,選擇乙個負權點即割掉其到t的邊。

現在證明方案合法。

對於依賴關係i到j:

假設i點權為正j點權為負。選了i不選j即沒有割掉s到i的邊而且沒有割掉j到t的邊,顯然s和t聯通,不符合最小割定義。

假設i點權為負j點權為正。選了i不選j即割掉i到t的邊而且割掉s到j的邊,由於s到t現在不連通,我們不割這兩條邊同樣s和t是不聯通的,那麼割這兩邊不滿足割量最小,不符合最小割定義。

其餘情況同理,不符合割量最小。

注意這個演算法不需要原圖是dag。

#include

#include

#include

#include

#include

#include

using

namespace

std;

#define n 4005

#define inf 2000000001

int n,m,a[n],b[n],k,x,c1,c2,s,t,sum,maxflow;

int tot,point[n],nxt[n*1000],v[n*1000],remain[n*1000];

int deep[n],cur[n],last[n],num[n];

queue

q;void addedge(int x,int y,int cap)

void bfs(int t)

}}int addflow(int s,int t)

now=t;

while (now!=s)

return ans;

}void isap(int s,int t)

bool has_find=false;

for (int i=point[now];i!=-1;i=nxt[i])

if (deep[v[i]]+1==deep[now]&&remain[i])

if (!has_find)

}}int main()

}isap(s,t);

printf("%d\n",sum-maxflow);

}

BZOJ3438 小M的作物

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

bzoj3438 小M的作物

題目鏈結 先考慮沒有額外收益的時候怎麼做。從 s 向第 i 點連一條容量為 a i 邊,表示種在 a 中的收益。從第 i 個點向 t 連一條容量為 b i 的邊,表示種在 b 中的收益。然後求出來最小割,用總收益減去即可。完成之後如下圖 然後考慮如何處理額外收益 對於每乙個額外的收益,我們先新建乙個...

bzoj3438 小M的作物

這題是一道最大權閉合圖的經典難題 by rose max upd 不誤人子弟了,這就是乙個裸的最小割啊。然後構圖的方式就是把作物值分成ab集合,乙個在st一邊,乙個在ed一邊,st連作物流量為a i 作物流ed流量為b i 對於每乙個組合,新建兩個點,乙個被st流流量為c1,乙個流ed流量為c2,然...