這道題的難點主要在於處理乙個人可以對區間產生貢獻這個限制。
我們之前都是將乙個人當成流量,但是這一容量的流量可以對乙個區間的點產生貢獻,這就導致這個問題無法處理。
於是考慮怎麼將乙個點可以對乙個區間產生貢獻在圖上表示出來:
我們考慮每一天,從\(s\)向\(1\)連容量為\(inf\)的邊,從\(i\)向\(i+1\)連容量為\(inf-a_i\)邊的邊,從\(n+1\)向\(t\)連容量為\(inf\)的邊,這些邊費用都是\(0\)。要滿足條件的話,我們就要保證了最大流為\(inf\)。
接下來,對於每種志願者\(i\),我們從\(s_i\)向\(t_i+1\)連容量為\(inf\)的邊,費用為\(c_i\)。
為什麼這麼建圖:
考慮每一天\(i\),我們要使最大流為\(inf\),而\(i\)的出邊容量為\(inf-a_i\),少了\(a_i\),那麼這\(a_i\)必定要由志願者代表的邊產生流量補上。乙個志願者能補\([s_i,t_i]\)的所有天,因此我們從\(s_i\)向\(t_i+1\)連邊。
這道題思路很巧妙,它用補充流量的方法使得一單位的流量能對乙個區間產生貢獻。
code:
#includeusing namespace std;
const int maxn=1010;
const int maxm=10010;
const int inf=1e9;
int n,m,cnt_edge=1,s,t;
int head[maxn],dis[maxn];
bool vis[maxn];
struct edgee[(maxn+maxm)<<1];
inline void add(int u,int v,int w,int c)
inline void addflow(int u,int v,int w,int c)
inline int read()
while(c>='0'&&c<='9')res=res*10+c-'0',c=getchar();
return res*f;
}inline bool spfa()}}
return dis[t]!=0x3f3f3f3f;
}int dfs(int x,int lim)
return lim-res;
}inline int dinic()
return cost;
}int main()
printf("%d",dinic());
return 0;
}
P3980 NOI2008 志願者招募 網路流
題意 一共有n 天 每天需要ai個志願者 有m種志願者 每種志願者可以從 第si 天工作到ti 天 每個需要ci元 問花最少的錢滿足每天的需求 顯然是費用流 如果正常連邊的話 每個志願者對其輻射的天非常難處理 可以採用時間軸的連法 源點連第一天 匯點連最後一天 容量為inf費用為0 這樣跑網路流是沿...
洛谷 P3980 NOI2008 志願者招募
我居然現在才會用費用流解線性規劃 當然這裡解決的一類問題比較特殊 以式子作為點,變數作為邊,然後要求就是變數在不同的式子裡出現了兩次,係數一次為 1,一次為 1 這樣的話就作為了乙個出度和乙個入度,和邊正好對應了 我們設每種志願者選擇人數是 x 我們的限制是 left x geq 0 x x geq...
luoguP2254 NOI2005 瑰麗華爾茲
題目比較好,人比較菜。include define maxn 205 using namespace std int n,m,x,y,k,f maxn maxn maxn l,r,d,dx 7 dy 7 l,r,q maxn ans 0 char tu maxn maxn int main mems...