費用流 動態加邊 NOI2012 美食節

2022-05-20 07:53:00 字數 2256 閱讀 3422

輸入檔案的第1行包含兩個正整數n和m,表示菜品的種數和廚師的數量。 第2行包含n個正整數,其中第i個數為pi,表示點第i種菜品的人數。 接下來有n行,每行包含m個非負整數,這n行中的第i行的第j個數為ti,j,表示第j個廚師製作第i種菜品所需的時間。 輸入檔案中每行相鄰的兩個數之間均由乙個空格隔開,行末均沒有多餘空格。

輸出僅一行包含乙個整數,為總等待時間的最小值。

3 2

3 1 1

5 7

3 6

8 9

47【樣例說明】

廚師1先製作1份菜品2,再製作2份菜品1。點這3道菜的3個同學的等待時間分別為3,3+5=8,3+5+5=13。

廚師2先製作1份菜品1,再製作1份菜品3。點這2道菜的2個同學的等待時間分別為7,7+9=16。

總等待時間為3+8+13+7+16=47。

雖然菜品1和菜品3由廚師1製作更快,如果這些菜品都由廚師1製作,總等待時間反而更長。如果按上述的做法,將1份菜品1和1份菜品3調整到廚師2製作,這樣廚師2不會閒著,總等待時間更短。

可以證明,沒有更優的點餐方案。

【資料規模及約定】

對於100%的資料,n <= 40, m <= 100, p <= 800, ti,j <= 1000(其中p = ∑pi,即點菜同學的總人數)。

每組資料的n、m和p值如下:

測試點編號 n m p

1 n = 5 m = 5 p = 10

2 n = 40 m = 1 p = 400

3 n = 40 m = 2 p = 300

4 n = 40 m = 40 p = 40

5 n = 5 m = 40 p = 100

6 n = 10 m = 50 p = 200

7 n = 20 m = 60 p = 400

8 n = 40 m = 80 p = 600

9 n = 40 m = 100 p = 800

10 n = 40 m = 100 p = 800

建圖方式和【費用流】[bzoj1070]/[hysbz1070]修車

類似,不過這道題的資料範圍大多了,直接跑顯然會tle。 影響s

pfa效率的主要是邊的數量,那我們動態加邊好了。

一開始我們只將菜和廚師所拆出的最後乙個點連邊。如果從乙個廚師那裡增廣了,我們再將菜那個廚師拆成的前乙個點連邊。我們可以保證,最短路一定在我們已經連了的邊中,所以不會出錯。

#include

#include

#include

#include

#define inf 0x7fffffff

#define maxn 40

#define maxm 100

#define maxp 800

using

namespace

std;

queue

q;void read(int &x)

}int n,m,tm[maxn+10][maxm+10],s,t,tot,dist[maxp*maxm+maxn+10],p,pp[maxn+10];

bool vis[maxp*maxm+maxn+10];

struct node*adj[maxp*maxm+maxn+10],edge[maxp*maxm*maxn+10],*ecnt=edge,*pre[maxp*maxm+maxn+10];

inline

void addedge(int u,int v,int cap,int wt)

bool spfa()

}return dist[t]!=inf;

}inline

int get_id(int i,int j)

inline

int get_cook(int id)

inline

int get_dish(int id)

void read()

int mcmf()

flow+=delta;

pos=pre[t]->back->v-1;

cook=get_cook(pos);

dish=get_dish(pos);

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

addedge(i,pos,1,tm[i][cook]*(::p-dish+1));

addedge(pos,t,1,0);

}return cost;

}int main()

NOI2012 美食節(費用流 動態開點)

題解 費用流 首先確定 每一單位的流量代表一位廚師做乙份菜品,費用代表花費的時間 每位廚師做同一道菜,每乙份時間也是不同的,因此將每個廚師拆成p個點 建邊需要確定的費用與做菜順序有關,而後做的菜對先做的菜是沒有影響的,所以倒著處理,拆成的第i個點表示每位廚師做的倒數第i道菜 建圖 s n種菜品 容量...

NOI2012 美食節 動態加邊維護費用流

現在有 n 種人,每種人有pi 個,還有 m 個廚師,第 j個廚師給第 i 種人做菜需要時間ti j,並且同一時間乙個廚師只能做一道菜。每個人的權值是這個人等待的時間。問所有人的權值和最小是多少。n 40 m 100 p i 800 設s um pi。我們考慮用網路流做這題,我們把第 i 個廚師差拆...

NOI2012 美食節 費用流

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