description
你的公司接到了一批訂單。訂單要求你的公司提供n類產品,產品被編號為1~n,其中第i類產品共需要ci件。公司共有m名員工,員工被編號為1~m員工能夠製造的產品種類有所區別。一件產品必須完整地由一名員工製造,不可以由某名員工製造一部分配件後,再轉交給另外一名員工繼續進行製造。
我們用乙個由0和1組成的m*n的矩陣a來描述每名員工能夠製造哪些產品。矩陣的行和列分別被編號為1~m和1~n,ai,j為1表示員工i能夠製造產品j,為0表示員工i不能製造產品j。
如果公司分配了過多工作給一名員工,這名員工會變得不高興。我們用憤怒值來描述某名員工的心情狀態。憤怒值越高,表示這名員工心情越不爽,憤怒值越低,表示這名員工心情越愉快。員工的憤怒值與他被安排製造的產品數量存在某函式關係,鑑於員工們的承受能力不同,不同員工之間的函式關係也是有所區別的。
對於員工i,他的憤怒值與產品數量之間的函式是乙個si+1段的分段函式。當他製造第1~ti,1件產品時,每件產品會使他的憤怒值增加wi,1,當他製造第ti,1+1~ti,2件產品時,每件產品會使他的憤怒值增加wi,2……為描述方便,設ti,0=0,ti,si+1=+∞,那麼當他製造第ti,j-1+1~ti,j件產品時,每件產品會使他的憤怒值增加wi,j, 1≤j≤si+1。
你的任務是制定出乙個產品的分配方案,使得訂單條件被滿足,並且所有員工的憤怒值之和最小。由於我們並不想使用special judge,也為了使選手有更多的時間研究其他兩道題目,你只需要輸出最小的憤怒值之和就可以了。
input
第一行包含兩個正整數m和n,分別表示員工數量和產品的種類數;
第二行包含n 個正整數,第i個正整數為ci;
以下m行每行n 個整數描述矩陣a;
下面m個部分,第i部分描述員工i的憤怒值與產品數量的函式關係。每一部分由三行組成:第一行為乙個非負整數si,第二行包含si個正整數,其中第j個正整數為ti,j,如果si=0那麼輸入將不會留空行(即這一部分只由兩行組成)。第三行包含si+1個正整數,其中第j個正整數為wi,j。
output
僅輸出乙個整數,表示最小的憤怒值之和。
sample input
2 3
2 2 2
1 1 0
0 0 1
1 2
1 10
1 2
1 6sample output
24分析:
費用流
我一開始yy的一種建圖方法,如下:
結果2500ms的時候wa,估計是4、5個點的時候
結果看到乙個前輩說
然後就a了
但是挺慢的。。卡時過
這裡寫**片
#include
#include
#include
#define ll long long
using namespace std;
const int inf=0x33333333;
const int n=100000;
struct node;
node way[n*10];
int st[n],tot=-1,pre[n],dis[n],q[n],tou,wei,cnt;
int n,m,ci[n],mp[300][300],s[n],t[300][10],w[300][10],s,t;
bool p[n];
void add(int u,int w,int v,int cc)
int spfa(int
s,int t)
}p[r]=1;
}while (toureturn dis[t]!=inf;
}void doit()
printf("%lld",ans);
}void lianbian()
tt++;
add(now,tt,inf,0); //最後一級
for (k=1;k<=m;k++)
if (mp[i][k]) add(tt,k+cnt,inf,w[i][s[i]+1]);
}for (i=1;i<=m;i++) add(i+cnt,t,ci[i],0);
}int main()
lianbian();
doit();
return
0;}
後來看到網上
用了一種拆邊的方法,可以把邊數大幅度減少
減少了迴圈邊和點入隊的時間
時間直接變成了開始的1/4
這裡寫**片
#include
#include
#include
#define ll long long
using namespace std;
const int inf=0x33333333;
const int n=50000;
struct node;
node way[n*10];
int st[n],tot=-1,pre[n],dis[n],q[n],tou,wei;
int n,m,ci[n],mp[300][300],s[n],t[300][10],w[300][10],s,t;
bool p[n];
void add(int u,int w,int v,int cc)
int spfa(int
s,int t)
}p[r]=1;
}while (toureturn dis[t]!=inf;
}void doit()
printf("%lld",ans);
}void lianbian()
for (i=1;i<=m;i++)
add(i+n,t,ci[i],0);
}int main()
lianbian();
doit();
return
0;}
bzoj2245 SDOI2011 工作安排
description 你的公司接到了一批訂單。訂單要求你的公司提供n類產品,產品被編號為1 n,其中第i類產品共需要ci件。公司共有m名員工,員工被編號為1 m員工能夠製造的產品種類有所區別。一件產品必須完整地由一名員工製造,不可以由某名員工製造一部分配件後,再轉交給另外一名員工繼續進行製造。我們...
BZOJ2245 SDOI2011 工作安排
題意 自行腦補,看懂分段函式是什麼即可。思路 顯然是最小費用最大流。對於每乙個工作人員的每一段,從原點到工作人員相應的點連一條費用與流量與這一段其相適應的邊。對於每乙個部件。從其相應的點到匯點連一條流量為須要的數目,費用為0的邊。然後就能夠出解了。建模還是非常顯然的。還有這題我寫spfa的多路增廣t...
BZOJ 2245 SDOI2011 工作安排
你的公司接到了一批訂單。訂單要求你的公司提供n類產品,產品被編號為1 n,其中第i類產品共需要ci 件。公司共有m名員工,員工被編號為1 m員工能夠製造的產品種類有所區別。一件產品必須完整地由一名員工製造,不可以由某名員工製造一部分配件後,再轉交給另外一名員工繼續進行製造。我們用乙個由0和1組成的m...