BZOJ2879 美食節(費用流)

2021-08-20 22:00:42 字數 1684 閱讀 3814

bzoj

洛谷一眼就會思路了吧。

把每個廚師拆點,拆分為他最多能要做的菜的個數,即∑p

i ∑pi

然後把每個菜向廚師的每個點連邊,表示這個菜是這個廚師做的第幾個菜。

考慮一下這個菜放在這個位置對於後面所有位置的影響就好了。

然後跑費用流就好了。

經蘿蔔提醒,上面這個東西就是scoi2007修車那道題目

然而這樣會掛,∑p

i≤32000

∑ pi

≤32000

,加上廚師個數

大概是∑pi

×m≤3200000

∑ pi

×m

≤3200000

有點**。

考慮一下費用流是怎麼做的:每次sp

fas pf

a找到一條費用最小的點,

在上述模型中,具有費用的唯一的邊就是從菜品到廚師拆出來的點,

並且我們知道,每次對於後面所有位置的影響需要乘上的倍數是遞增的。

所以我們從小往大連邊,保證每次sp

fas pf

a跑出來的結果一定是全域性的最優結果

每次增廣出來一條路徑,就對於增廣的這個廚師額外增加乙個點連進來就好了。

似乎有點簡單了?今天碼風好迷啊

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

#define ll long long

#define rg register

#define max 88888

inline

int read()

struct linee[max<<2];

int h[max],cnt=2;

inline

void add(int u,int v,int w,int fy)

;h[u]=cnt++;

e[cnt]=(line);h[v]=cnt++;

}queue

q;int pv[max],pe[max],s,t,flow,cost,dis[max];

bool inq[max];

bool spfa()

}inq[u]=false;

}if(dis[t]>=1e9)return

false;

int flow=1e9;

for(int i=t;i!=s;i=pv[i])flow=min(flow,e[pe[i]].w);

for(int i=t;i!=s;i=pv[i])e[pe[i]].w-=flow,e[pe[i]^1].w+=flow;

cost+=flow*dis[t];

return

true;

}int n,m,t[111][111],a[111],tot;

int bl[max];

int main()

while(spfa())

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

return

0;}

BZOJ 2879 美食節(費用流 動態加邊)

題意 有n道菜,每道菜需要b i 份,m個廚師,第j個廚師做第i道菜需要時間a i j 求做完所有菜,所有人等待的最小總時間。思路 設所有的菜為sum。乙個明顯的思路是將每個廚師拆成sum個點。然後sum個菜每個菜向每個廚師的每個點連邊,表示該道菜為該廚師第幾個做。由於這樣資料太大。動態加邊。每次增...

C 之路高階 bzoj2879(美食節)

time limit 10 sec memory limit 512 mb submit 1304 solved 702 submit status discuss 輸入檔案的第1行包含兩個正整數n和m,表示菜品的種數和廚師的數量。第2行包含n個正整數,其中第i個數為pi,表示點第i種菜品的人數。接...

NOI2012 美食節 費用流

題目描述 題解 一開始按照修車那題的思路搞了個費用流,就是把廚師拆成tim個點,表示他是倒數第幾個做的,然後邊權就是對後面的人的代價和,然後t到飛起。原因是直接把圖建出來導致圖的規模過大,然後spfa就死了。所以我們可以動態加邊,每增廣一次就加乙個點。include include include ...