bzoj 1061 志願者招募

2021-07-07 05:33:03 字數 1348 閱讀 8677

明顯的線性規劃網路流,據說當時考場上就1個人a了?

a[i][j]表示第i種志願者第j天是否工作

p[i]表示第i種志願者的人數

sigma(a[i][x]*p[i])>=need[x]

補充函式y[i],則sigma(a[i][x]*p[i])=need[x]+y[x]

差分,start[i]表示第i種志願者開始工作的時間,end[i]表示第i種志願者結束工作的時間

sigma(p[i]*(start[i]==1))=need[1]+y[1] 1

-sigma(p[i]*(start[i]==x))+sigma(p[i]*(end[i]==x-1))=need[x]-need[x-1]+p[x]-p[x-1] x

sigma(p[i]*(end[i]==day))=-need[n]-y[n] n+1

#include

#include

#include

#include

#include

#define md

#define ll long long

#define inf (int) 1e9

#define eps 1e-8

#define n 200010

#define m 200010

using namespace std;

struct yts e[2*m];

int dis[n],vis[n],path[n],flow[n],q[n],v[n];

int p[n];

int num=1,s,t,ans=0;

void put(int x,int y,int f,int c)

void add(int x,int y,int f,int c)

bool spfa()}}

vis[x]=0;

}if (dis[t]==inf) return 0;

int f=flow[t]; ans+=dis[t]*f;

path[s]=0;

for (int x=t,i=path[x];x!=s;x=e[i].x,i=path[x])

return 1;

}void outit()

int main()

add(n+2,t,p[n],0);

for (int i=1;i<=m;i++)

//outit();

for (int i=0;i<=n;i++) add(i+2,i+1,inf,0);

while (spfa());

printf("%d\n",ans);

return 0;

}

BZOJ 1061, 志願者招募

傳送門 最小化招聘給定不同型別志願者,以滿足每日不同人數要求的費用總和。由線性規劃轉化為最小費用最大流來處理。一般按如下步驟進行操作 新增鬆弛變數,將不等號都變為等號。分別用下乙個式子減去上乙個式子,如果每個變數只出現了兩次且符號一正一負,那麼可以轉化為費用流。對於每個式子建立乙個點,那麼每個變數對...

bzoj1061 志願者招募

題意 給m類志願者,第i個志願者從第 l i 天工作到第 r i 天,費用為c i 每種志願者可以選擇無限多人。每一天都有給定的最少志願者數目要求a i 求費用最小的選擇方案,輸出費用。思路 明顯是一道線性規劃可以解決的問題,但我不會寫單純型。聽溪哥說線性規劃都有網路流的等價形式,不過我在網上沒有找...

BZOJ 1061 志願者招募

思路 可以用不等式的改裝變成費用流.將不等式列出,如果有負的常數,那麼就從等式連向t,如果是正的就從s連向等式,流量為常數,費用為0。如果是變數,那麼找出都有這個變數的兩個等式,從負的連向正的流量為inf的邊,如果有費用,那就再加上費用。1 include2 include3 include4 in...