洛谷 P1251 餐巾計畫問題

2021-08-13 09:23:55 字數 1525 閱讀 8333

吃什麼

先說建圖:

經典構圖題。將每一天拆成兩個點i,

i′,加如下6條邊: (s

,i,r

i,p)

——在第

i 天可以買至多ri

個餐巾,每塊

p 分; (i

,t,r

i,0)

——第i

天要用ri

塊餐巾; (s

,i′,

ri,0

) ——第

i 天用剩的ri

塊舊餐巾; (i

′,i+

m,∞,

f)——第

i 天的舊餐巾送到快洗部,每塊

f分; (i

′,i+

n,∞,

s)——第

i 天的舊餐巾送到慢洗部,每塊

s分; (i

′,i′

+1,∞

,0) ——第

i 天的舊餐巾可以留到第i+

1天再處理;

求一次最小費用流即為結果。

思路是把每個點拆開

乙個代表獲得當天所需的餐巾需要購買新的餐巾所造成的花費

另乙個代表處理當天用掉的餐巾造成的花費

兩個加起來就是當天的花費

流量限制每天的餐巾紙不大於ri

然後跑最小費用最大流

而最大流一定可以保證滿足每天的餐巾紙數量

即可以在滿足每一天的餐巾紙數量的情況下取得最小花費

// by spli

#include

#include

#include

#include

#include

#define int long long

using

namespace

std;

typedef pair pair;

const

int n=2010

<<1;

const

int m=n*6;

const

int inf=0x3f3f3f3f;

int n;

int r[n];

int pp,ff,mm,nn,ss;

struct nodee[m*2];int head[n],cnt;

int pv[n],pe[n];

queue

q;bool vis[n];

int dis[n];

void add(int f,int t,int fl,int c);

head[f]=cnt++;

}void add_edge(int f,int t,int fl,int c)

bool spfa(int s,int t)}}

}return dis[t]int s,int t)

return pair(f,c);

}main()

pair ans=mcf(s,t);

cout

0;}

洛谷 P1251餐巾計畫問題 題解

傳送門 乙個餐廳在相繼的 n 天裡,每天需用的餐巾數不盡相同。假設第 i 天需要 r i 塊餐巾 i 1,2,n 餐廳可以購買新的餐巾,每塊餐巾的費用為 p 分 或者把舊餐巾送到快洗部,洗一塊需 m 天,其費用為 f 分 或者送到慢洗部,洗一塊需 n 天 n m 其費用為 s 分 s 每天結束時,餐...

P1251 餐巾計畫問題

題面 一道特別棒的費用流好題,思路非常巧妙 對於每一天,我們分為早上和晚上兩個節點 每天早上會消耗 r i 條乾淨的毛巾,可以視為流向匯點,所以我們向匯點連一條流量為 r i 費用為 0 的邊 每天晚上會產生 r i 條髒毛巾,可以視為從源點流出,所以我們從源點連一條流量為 r i 費用為 0 的邊...

P1251 餐巾計畫問題

因為髒的衣服在一天結束時才會有,乾淨的一天開始才會有,考慮拆點。再考慮乾淨的衣服都是要被收集起來的,所以乾淨的要流向超匯。而髒的衣服可以從超源免費獲得所需要的個數,而乾淨的衣服只能購買。看張圖吧,假如只有 1 個點的話,且需要無限多的衣服。顯然前者正確,後者矛盾 收集了髒衣服 再者,這種建圖會無法收...