poj3762 The Bonus Salary! (mcmf 区间K覆盖问题)
来源:互联网 发布:windows ab 压力测试 编辑:程序博客网 时间:2024/06/01 09:30
Description
In order to encourage employees’ productivity, ACM Company has made a new policy. At the beginning of a period, they give a list of tasks to each employee. In this list, each task is assigned a “productivity score”. After the first K days, the employee who gets the highest score will be awarded bonus salary.
Due to the difficulty of tasks, for task i-th:
- It must be done from hh_Li : mm_Li : ss_Li to hh_Ri : mm_Ri : ss_Ri.
- This range of time is estimated very strictly so that anyone must use all of this time to finish the task.
Moreover, at a moment, each employee can only do at most one task. And as soon as he finishes a task, he can start doing another one immediately.
XYY is very hard-working. Unfortunately, he’s never got the award. Thus, he asks you for some optimal strategy. That means, with a given list of tasks, which tasks he should do in the first K days to maximize the total productivity score. Notice that one task can be done at most once.
Input
The first line contains 2 integers N and K (1 ≤ N ≤ 2000, 0 ≤ K ≤ 100), indicating the number of tasks and days respectively. This is followed by N lines; each line has the following format:
hh_Li:mm_Li:ss_Li hh_Ri:mm_Ri:ss_Ri w
Which means, the i-th task must be done from hh_Li : mm_Li : ss_Li to hh_Ri : mm_Ri : ss_Ri and its productivity score is w. (0 ≤hh_Li, hh_Ri ≤ 23, 0 ≤mm_Li, mm_Ri, ss_Li, ss_Ri ≤ 59, 1 ≤ w ≤ 10000). We use exactly 2 digits (possibly with a leading zero) to represent hh, mm and ss. It is guaranteed that the moment hh_Ri : mm_Ri : ss_Ri is strictly later than hh_Li : mm_Li : ss_Li.
Output
The output only contains a nonnegative integer — the maximum total productivity score.
Sample Input
5 2
09:00:00 09:30:00 2
09:40:00 10:00:00 3
09:29:00 09:59:00 10
09:30:00 23:59:59 4
07:00:00 09:31:00 3
Sample Output
16
这道题就是一个区间K覆盖问题的模版把。。
感觉以后这种问题都可以转化为费用流来解决。
费用流建图:
离散化,然后对离散化之后的点相互之间连一条边,费用0,容量inf或者至少k都行。然后离散化之后的区间左右端点连一条边,费用-w(因为要求最大的,而我们的是mcmf),容量为1,表示只能选一次,然后连上超级源点超级汇点,容量均为k,费用为0。这里的容量不能为inf,因为要选k次。
#include<iostream>using namespace std;#include<cstdio>#include<cstring>#include<algorithm>#include<assert.h>#include<queue>const int maxn=5005;const int maxm=13000;const int inf=0x3f3f3f3f;int head[maxn];struct note { int to,next,cap,flow,cost;} edge[maxm];struct notes { int start,ends,nums;} in[2005];int n,m,top;int pre[maxn];int d[maxn];bool used[maxn];int que[maxm*100];inline void ADD(int u,int v,int f,int w) { edge[top].cap=f; edge[top].flow=0; edge[top].to=v; edge[top].cost=w; edge[top].next=head[u]; head[u]=top++; edge[top].cap=0; edge[top].flow=0; edge[top].to=u; edge[top].cost=-w; edge[top].next=head[v]; head[v]=top++;}bool spfa(int s,int t) { memset(d,inf,sizeof(d)); memset(used,false,sizeof(used)); memset(pre,-1,sizeof(pre)); d[s]=0,used[s]=true; int f=0,last=0; que[last++]=s; while(f<last) { int now=que[f++]; used[now]=false; for(int i=head[now]; ~i; i=edge[i].next) { int to=edge[i].to; if((edge[i].flow<edge[i].cap)&&(edge[i].cost+d[now]<d[to])) { d[to]=d[now]+edge[i].cost; pre[to]=i; if(!used[to]) { used[to]=true; que[last++]=to; } } } } return d[t]!=inf;}void mcmf(int s,int t,int& cost) { cost=0; int Min; while(spfa(s,t)) { Min=inf; for(int i=pre[t]; ~i; i=pre[edge[i^1].to]) { if(Min>(edge[i].cap-edge[i].flow)) { Min=edge[i].cap-edge[i].flow; } } for(int i=pre[t]; ~i; i=pre[edge[i^1].to]) { edge[i].flow+=Min; edge[i^1].flow-=Min; cost+=edge[i].cost*Min; } }}int H[5105];int fuck(int val1,int val2,int val3) { return val1*60*60+val2*60+val3;}void Init() { top=0; memset(head,-1,sizeof(head));}int main() {#ifdef tangge freopen("3762.txt","r",stdin);#endif // tangge int u,v,w; while(~scanf("%d%d",&n,&m)) { int s=0; Init(); for(int i=0; i<n; ++i) { scanf("%d:%d:%d",&u,&v,&w); in[i].start=fuck(u,v,w); scanf("%d:%d:%d",&u,&v,&w); in[i].ends=fuck(u,v,w); H[s++]=in[i].start; H[s++]=in[i].ends; scanf("%d",&in[i].nums); } sort(H,H+s); int len=unique(H,H+s)-H; int S=0,T=len+1; ADD(S,1,m,0); for(int i=1; i<len; ++i) { ADD(i,i+1,m,0); } ADD(len,T,m,0); for(int i=0; i<n; ++i) { int pos1=lower_bound(H,H+len,in[i].start)-H+1; int pos2=lower_bound(H,H+len,in[i].ends)-H+1; ADD(pos1,pos2,1,-in[i].nums); } int cost; mcmf(S,T,cost); printf("%d\n",-cost); } return 0;}
- poj3762 The Bonus Salary! (mcmf 区间K覆盖问题)
- POJ 3762 The Bonus Salary!(区间k覆盖问题)
- POJ 3762 The Bonus Salary!(最小K覆盖)
- POJ-3762-The Bonus Salary!
- POJ 3680 Intervals(区间k覆盖问题)
- POJ3680 Intervals (区间K覆盖问题)
- poj 3762 The Bonus Salary! 需离散化
- 【POJ】 3762 The Bonus Salary! 离散 + 费用流
- POJ 3762 The Bonus Salary! 最小费用最大流
- POJ 3762 The Bonus Salary!(费用流)
- POJ3762 时间段用k次
- The Bonus Salary! (poj 3762 离散化+最小费用流)
- 区间覆盖问题
- 区间覆盖问题
- 区间覆盖问题
- 区间覆盖问题
- 区间覆盖问题(sdut2074
- 区间覆盖问题
- uva 572 Oil Deposits
- 欢迎使用CSDN-markdown编辑器
- python 开发简单爬虫 by CL(一)
- HDU 1390 Binary Numbers
- popwondows简单用法
- poj3762 The Bonus Salary! (mcmf 区间K覆盖问题)
- Android错误:cannot locate symbol "rand" referenced by "libgameshared.so
- 二分的两种重要模型
- 二叉树---检查是否为BST
- 努力不一定会成功,不努力一定不成功!
- 初学C语言:特殊乘法(单个数字字符去减‘0’得到的就是数字)
- Java 数据类型初始值
- Java8(下)
- C++存储类别、类型修饰符、输入限定符