bzoj 2245 [SDOI2011]工作安排(最小费用最大流)

2245: [SDOI2011]工作安排

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 1197  Solved: 580
[ Submit][ Status][ Discuss]

Description

你的公司接到了一批订单。订单要求你的公司提供n类产品,产品被编号为1~n,其中第i类产品共需要Ci件。公司共有m名员工,员工被编号为1~m员工能够制造的产品种类有所区别。一件产品必须完整地由一名员工制造,不可以由某名员工制造一部分配件后,再转交给另外一名员工继续进行制造。

我们用一个由01组成的m*n的矩阵A来描述每名员工能够制造哪些产品。矩阵的行和列分别被编号为1~m1~nAi,j1表示员工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 1j≤Si+1。

你的任务是制定出一个产品的分配方案,使得订单条件被满足,并且所有员工的愤怒值之和最小。由于我们并不想使用Special Judge,也为了使选手有更多的时间研究其他两道题目,你只需要输出最小的愤怒值之和就可以了。

Input

第一行包含两个正整数mn,分别表示员工数量和产品的种类数;

第二行包含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 6

Sample Output

24

HINT

 

Source

【思路】

       最小费用最大流。

       构图连边。关于分段函数:只要连Tj-Tj-1容量W费用的边即可,因为题目中有Wi,j <Wi,j+1,所以简单地跑最小费用最大流。

 

【代码】

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<queue>
 4 #include<vector>
 5 #define FOR(a,b,c) for(int a=(b);a<(c);a++)
 6 using namespace std;
 7 
 8 typedef long long LL;
 9 const int maxn = 1000+10;
10 const LL INF = 1e9;
11 
12 struct Edge{ int u,v,cap,flow,cost;
13 };
14 
15 struct MCMF {
16     int n,m,s,t;
17     int inq[maxn],a[maxn],d[maxn],p[maxn];
18     vector<int> G[maxn];
19     vector<Edge> es;
20     
21     void init(int n) {
22         this->n=n;
23         es.clear();
24         for(int i=0;i<n;i++) G[i].clear();
25     }
26     void AddEdge(int u,int v,int cap,int cost) {
27         es.push_back((Edge){u,v,cap,0,cost});
28         es.push_back((Edge){v,u,0,0,-cost});
29         m=es.size();
30         G[u].push_back(m-2);
31         G[v].push_back(m-1);
32     }
33     
34     bool SPFA(int s,int t,int& flow,LL& cost) {
35         for(int i=0;i<n;i++) d[i]=INF;
36         memset(inq,0,sizeof(inq));
37         d[s]=0; inq[s]=1; p[s]=0; a[s]=INF; 
38         queue<int> q; q.push(s);
39         while(!q.empty()) {
40             int u=q.front(); q.pop(); inq[u]=0;
41             for(int i=0;i<G[u].size();i++) {
42                 Edge& e=es[G[u][i]];
43                 int v=e.v;
44                 if(e.cap>e.flow && d[v]>d[u]+e.cost) {
45                     d[v]=d[u]+e.cost;
46                     p[v]=G[u][i];
47                     a[v]=min(a[u],e.cap-e.flow);        //min(a[u],..)
48                     if(!inq[v]) { inq[v]=1; q.push(v);
49                     }
50                 }
51             }
52         }
53         if(d[t]==INF) return false;
54         flow+=a[t] , cost+= (LL) a[t]*d[t];
55         for(int x=t; x!=s; x=es[p[x]].u) {
56             es[p[x]].flow+=a[t]; es[p[x]^1].flow-=a[t];
57         }
58         return true;
59     }
60     int Mincost(int s,int t,LL& cost) {
61         int flow=0; cost=0;
62         while(SPFA(s,t,flow,cost)) ;
63         return flow;
64     }
65 } mc;
66 
67 int n,m;
68 int t[maxn];
69 
70 int main() {
71     //freopen("in.in","r",stdin);
72     //freopen("out.out","w",stdout); 
73     scanf("%d%d",&m,&n);
74     mc.init(m+n+2);
75     int S=m+n,T=S+1;
76     int c;
77     FOR(i,0,n) {
78         scanf("%d",&c);
79         mc.AddEdge(m+i,T,c,0);
80     }
81     FOR(i,0,m) FOR(j,0,n) {
82         scanf("%d",&c);
83         if(c) mc.AddEdge(i,j+m,INF,0);
84      }
85      FOR(i,0,m) {
86          scanf("%d",&c);
87          FOR(j,0,c) scanf("%d",&t[j]); t[c]=INF;
88          int w,tt;
89          FOR(j,0,c+1) {
90              scanf("%d",&w);
91              tt = j==0? t[0]:t[j]-t[j-1];
92              mc.AddEdge(S,i,tt,w);
93          }
94      }
95      LL cost;
96       mc.Mincost(S,T,cost);
97      printf("%lld\n",cost);
98      return 0;
99 }

 

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值