題解 洛谷P1361 小M的作物

2021-09-26 01:29:19 字數 1720 閱讀 7683

有兩塊容量為無限大的耕地a,b。對於每一種種子,種在a裡的收益為ai,種在b裡的收益為bi。特別地,對於m種組合,如果組合中的種子全部種在a裡,可以獲得c1的額外收益,全部種在b裡則可以獲得c2的額外收益。求最大的收益。

我們考慮對於一種種子要不在a地,要不在b地。當我們取其中一種情況時,就要把另一種捨去。如果在圖上有一條邊連線當前的種子和a,我們就要把將它和b連起來的邊斷開。

這不就是最小割嗎?!

但怎麼建圖呢?

顯然我們可以取a為源點,取b為匯點。對於任意一點,我們連一條從a到當前點的邊,容量為ai,再連一條從當前點到b的邊,容量為bi。

以上是最普通的情況,那麼對於那m種組合,我們應該怎麼去處理呢?

假設現在有一種組合對應著乙個點集,只要u和v中的任意乙個不在a中,我們就無法得到c1的額外收益。我們肯定不可以分別從a連向u,v,因為這個樣子即使到v的邊斷了,到u的邊依然有可能會使c1的額外收益流到匯點,但這並不合題意。

也就是說,我們需要有一條邊滿足只要這條邊被割斷,那麼c1的額外收益就肯定不會流到匯點。

那麼這條邊應該由a連向誰呢?顯然不可能是圖中原有的點了,因為不管是c1還是c2,都是這整個組合的額外收益,所以c1要能流入這個點集中的任意乙個點。

那麼解決方案就十分明顯了——建乙個虛點x,從a連一條邊到x,邊的容量為c1;再從x連向點集中的每乙個點,邊的容量為無窮大,即無法被割斷。

對於點集裡的點到b中的處理與以上相同。

根據最大流=最小割,我們只要在建好的圖上跑一遍最大流,並用所有的值減去求出的最小割(最少的取不到的價值),就能求出答案了。

這道題加了許多虛點和虛邊,所以陣列大小至少要為1e7

#include#define maxn 1000009

#define inf 0x7fffffff

using namespace std;

int cnt,to[maxn*2],val[maxn*2],next[maxn*2],head[maxn],cur[maxn*2];

int n,m,s,t,a[maxn],b[maxn],k,c1,c2,d[maxn],sum;

long long ans,all;

void add (int x,int y,int z)

void read ()

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

scanf("%d",&m);

sum=0;

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

add(n+sum+2+1,t,c2),add(t,n+sum+2+1,0);//連線點集和b的虛點

sum++; }}

bool bfs ()

} } if (d[t]!=-1)

return true;

else

return false;

}int dfs (int x,int low)

} if (low!=0)

d[x]=-1;

return totflow;

}void dinic ()

int main ()

{ cnt=-1;

memset(head,-1,sizeof(head));

read();

dinic();//跑一遍dinic

cout《剛學dinic,急著把板子揹著寫一遍,結果最後忘了要用總答案減去最小割,白調了半天tat

洛谷 P1361 小M的作物

有 nn n 種作物,兩塊耕地 a aa 和 bbb 第 i ii 種作物種植在 a aa 中收益為 a ia i ai 種植在 b bb 中收益為 b ib i bi 另有 m mm 種組合,每種組合有 k kk 種作物,如果這 k kk 種作物共同種在 a aa 中收益為 c1i c1 i c1...

P1361 小M的作物

p1361 小m的作物 二者取其一型別的網路流題 不同的集合,向對應元素連去不同 收益 容量的邊 對於那些神奇的組合,我們只需要按照以下方式建立兩個點 x 向 s 連一條在a時的額外收益 2.x x 注意順序,x 是其有向邊的起點,x 是其有向邊的終點 向其後繼節點連 inf 容量的邊,保證不會出現...

P1361 小M的作物

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