luoguP3980 NOI2008 志願者招募

2022-05-07 20:09:11 字數 1275 閱讀 2284

這道題的難點主要在於處理乙個人可以對區間產生貢獻這個限制。

我們之前都是將乙個人當成流量,但是這一容量的流量可以對乙個區間的點產生貢獻,這就導致這個問題無法處理。

於是考慮怎麼將乙個點可以對乙個區間產生貢獻在圖上表示出來:

我們考慮每一天,從\(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...