本題是修車的資料加強版
有數量限制和花費,考慮費用流建模
顯然,源點連線每個菜,流量為\(p_i\),廚師連向匯點,流量為\(inf\)
但是菜\(i\)和廚師\(j\)在不同時間的花費是不同的,具體來說,當它是倒數第\(k\)道菜時,它的花費為\(k\times a_\)
將廚師拆點,分別對應倒數第\(k\)道菜,連線菜和廚師,流量設為1,花費設為\(k\times a_\)
跑一遍費用流即可(?)
顯然這樣做邊是很多的,考慮優化
可以發現對於組合\((i,j,k)\)來說,它肯定在\((i,j,k+1)\)後面選,因為後者的花費永遠小於前者,那麼在\((i,j,k+1)\)被選之前,\((i,j,k)\)都沒有必要加入圖中
每求一次增廣路都將這一次選擇的那乙個組合\((i,j,k)\)的後乙個點\((i,j,k+1)\)加入即可
#include#define n 100005
#define m 5000005
using namespace std;
int n,m,p,p[n],a[45][105];
int s,t,ndsum;
int dis[n];
int pre[n],preedge[n],flow[n];
bool exist[n];
pairref[n];
struct edge
edge[m<<1]; int head[n],cnt=1;
void add_edge(int from,int to,int flow,int dis)
void add(int from,int to,int flow,int dis)
template inline t max(t a,t b)
template inline t min(t a,t b)
template void read(t &x)
bool spfa()
}} }
return (pre[t] != -1);
}int main()
int mincost=0;
while(spfa()) }
cout
}
NOI2012 美食節 費用流
題目描述 題解 一開始按照修車那題的思路搞了個費用流,就是把廚師拆成tim個點,表示他是倒數第幾個做的,然後邊權就是對後面的人的代價和,然後t到飛起。原因是直接把圖建出來導致圖的規模過大,然後spfa就死了。所以我們可以動態加邊,每增廣一次就加乙個點。include include include ...
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 個廚師差拆...