【SDOI2011】工作安排
【题目描述】
你的公司接到了一批订单。订单要求你的公司提供n类产品,产品被编号为1-n,其中第i类产品共需要Ci件。公司共有m名员工,员工被编号为1-m,不同的员工能够制造的产品种类有所区别。一件产品必须完整地由一名员工制造,不可以由某名员工制造一部分配件后,再转交给另外一名员工继续进行制造。
我们用一个由0和1组成的m*n的矩阵A来描述每名员工能够制造哪些产品。矩阵的行和列分别被编号为1-m和1-n,为1表示员工i能够制造产品j,为0表示员工i不能制造产品j。
如果公司分配了过多工作给一名员工,这名员工会变得不高兴。我们用愤怒值来描述某名员工的心情状态。愤怒值越高,表示这名员工心情越不爽,愤怒值越低,表示这名员工心情越愉快。员工的愤怒值与他被安排制造的产品数量存在某函数关系,鉴于员工们的承受能力不同,不同员工之间的函数关系也是有所区别的。
对于员工i,他的愤怒值与产品数量之间的函数是一个Si+1段的分段函数。当他制造第1-Ti,1件产品时,每件产品会使他的愤怒值增加Wi,1,当他制造第Ti,1+1-Ti,2件产品时,每件产品会使他的愤怒值增加……为描述方便,设Ti,0=0,Ti,si+1=无限大,那么当他制造第Ti,j-1+1-Ti,j件产品时,每件产品会使他的愤怒值增加Wi,j,1≤j≤Si+1。
你的任务是制定出一个产品的分配方案,使得订单条件被满足,并且所有员工的愤怒值之和最小。由于我们并不想使用Special Judge,你只需要输出最小的愤怒值之和就可以了。
【输入】
第一行包含两个正整数m和n,分别表示员工数量和产品的种类数;
第二行包含n个正整数,第i个正整数为Ci;
以下m行每行n个整数描述矩阵A;
下面m个部分,第i部分描述员工的愤怒值与产品数量的函数关系。每一部分由三行组成:第一行为一个非负整数Si,第二行包含个Si正整数,其中第j个正整数为Ti,j,如Si=0那么输入将不会留空行(即这一部分只由两行组成)。第三行包含个正整数Si+1,其中第j个正整数为Wi,j。
【输出】
仅输出一个整数,表示最小的愤怒值之和。
【输入样例】
2 3
2 2 2
1 1 0
0 0 1
1
2
1 10
1
2
1 6
【输出样例】
24
【数据范围】
存在30%的数据,m,n≤30;
均匀分布着约30%的数据,满足Si=0;
均匀分布着约30%的数据,满足Si≤1(不包含上述的数据);
对于100%的数据,1≤m,n≤250,0≤Si≤5,0≤Ai,j≤1,0<Ti,j<Ti,j+1,0<Wi,j<Wi,j+1,所有数据不大于10^5。
【题解】
这道题算法是最小费用流,但要处理好图中的边。
虚拟一个源点与所有产品相连,流量为产品需求量,费用为0。每个产品与能生产该产品的员工相连,流量为∞,费用为0。
接下来应该把员工向虚拟的汇点连边,不过这些边的费用是变化的,所以我们拆分成多条平行边,流量为T(i)-T(i-1),费用为Wi。因为费用流在执行过程中会先找到费用小的边,而平行边的费用是单调递增的,所以这样的策略总能保证先通过怒气值小的边,等这些边满流后才会跑怒气值大的边。
以前做过的费用流都是拆点,拆边是第一次做,似乎费用是函数变化的最小费用流都是这个思路。
【代码】
时限是充足的,费用流的题时限都充足,于是很懒很懒的我就不想看zkw费用流了TwT