明顯的線性規劃網路流,據說當時考場上就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...