Machine Programming

题目连接:

http://codeforces.com/problemset/problem/164/B

Descriptionww.co

One remarkable day company "X" received k machines. And they were not simple machines, they were mechanical programmers! This was the last unsuccessful step before switching to android programmers, but that's another story.

The company has now n tasks, for each of them we know the start time of its execution si, the duration of its execution ti, and the company profit from its completion ci. Any machine can perform any task, exactly one at a time. If a machine has started to perform the task, it is busy at all moments of time from si to si + ti - 1, inclusive, and it cannot switch to another task.

You are required to select a set of tasks which can be done with these k machines, and which will bring the maximum total profit.

Input

The first line contains two integer numbers n and k (1 ≤ n ≤ 1000, 1 ≤ k ≤ 50) — the numbers of tasks and machines, correspondingly.

The next n lines contain space-separated groups of three integers si, ti, ci (1 ≤ si, ti ≤ 109, 1 ≤ ci ≤ 106), si is the time where they start executing the i-th task, ti is the duration of the i-th task and ci is the profit of its execution.

Output

Print n integers x1, x2, ..., xn. Number xi should equal 1, if task i should be completed and otherwise it should equal 0.

If there are several optimal solutions, print any of them.

Sample Input

3 1

2 7 5

1 3 3

4 1 3

Sample Output

0 1 1

Hint

题意

有n个任务,m个机器,每个机器同一时间只能处理一个任务

每个任务开始时间为s,持续时间为t,做完可以赚c元

问你做哪几个任务可以拿到最多的钱

输出方案

题解:

费用流

离散化每个任务的开始时间和结束时间,然后建图跑一遍就好了

把所有时间扔到一个队列里面排序

然后建立源点到最开始任务的起始时间-第二个时间-第三个时间-....-最后一个时间点-汇点,期间流量都是m,花费为0

然后对于每一个任务,连一条开始时间到结束时间+1的边,花费为-c,流量为1的

然后这样跑费用流一定就是答案了

代码

#include<bits/stdc++.h>
using namespace std; const int MAXN = 10000;
const int MAXM = 100000;
const int INF = 0x3f3f3f3f;
struct Edge
{
int to, next, cap, flow, cost;
int id;
int x, y;
} edge[MAXM],HH[MAXN],MM[MAXN];
int head[MAXN],tol;
int pre[MAXN],dis[MAXN];
bool vis[MAXN];
int N, M;
void init()
{
N = MAXN;
tol = 0;
memset(head, -1, sizeof(head));
}
int addedge(int u, int v, int cap, int cost, int id)//左端点,右端点,容量,花费
{
edge[tol]. to = v;
edge[tol]. cap = cap;
edge[tol]. cost = cost;
edge[tol]. flow = 0;
edge[tol]. next = head[u];
edge[tol]. id = id;
int t = tol;
head[u] = tol++;
edge[tol]. to = u;
edge[tol]. cap = 0;
edge[tol]. cost = -cost;
edge[tol]. flow = 0;
edge[tol]. next = head[v];
edge[tol]. id = id;
head[v] = tol++;
return tol;
}
bool spfa(int s, int t)
{
queue<int>q;
for(int i = 0; i < N; i++)
{
dis[i] = INF;
vis[i] = false;
pre[i] = -1;
}
dis[s] = 0;
vis[s] = true;
q.push(s);
while(!q.empty())
{
int u = q.front();
q.pop();
vis[u] = false;
for(int i = head[u]; i != -1; i = edge[i]. next)
{
int v = edge[i]. to;
if(edge[i]. cap > edge[i]. flow &&
dis[v] > dis[u] + edge[i]. cost )
{
dis[v] = dis[u] + edge[i]. cost;
pre[v] = i;
if(!vis[v])
{
vis[v] = true;
q.push(v);
}
}
}
}
if(pre[t] == -1) return false;
else return true;
}
//返回的是最大流, cost存的是最小费用
int minCostMaxflow(int s, int t, int &cost)
{
int flow = 0;
cost = 0;
while(spfa(s,t))
{
int Min = INF;
for(int i = pre[t]; i != -1; 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 != -1; i = pre[edge[i^1]. to])
{
edge[i]. flow += Min;
edge[i^1]. flow -= Min;
cost += edge[i]. cost * Min;
}
flow += Min;
}
return flow;
}
struct node
{
int st,et,ct;
int id;
}task[MAXN];
bool cmp(node A,node B)
{
if(A.st==B.st)return A.et<B.et;
return A.st<B.st;
}
map<int,int> H;
vector<int> V;
int id[3000];
int main()
{
int n, m;
scanf("%d%d",&n,&m);
init();
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&task[i].st,&task[i].et,&task[i].ct);
task[i].et+=task[i].st-1;
task[i].id=i;
V.push_back(task[i].st);
V.push_back(task[i].et);
} sort(V.begin(),V.end());
V.erase(unique(V.begin(),V.end()),V.end()); for(int i=0;i<V.size();i++)
H[V[i]]=i+1;
for(int i=1;i<=V.size();i++)
addedge(i-1,i,m,0,0);
addedge(V.size(),V.size()+1,m,0,0);
addedge(V.size()+1,V.size()+2,m,0,0);
for(int i=1;i<=n;i++)
id[i]=addedge(H[task[i].st],H[task[i].et]+1,1,-task[i].ct,i);
int ans1=0,ans2=0;
ans1=minCostMaxflow(0,V.size()+2,ans2);
//printf("%d\n",ans2);
for(int i=1;i<=n;i++)
printf("%d ",edge[id[i]-2].flow);
return 0;
}

CodeForces 164C Machine Programming 费用流的更多相关文章

  1. Codeforces 708D 上下界费用流

    给你一个网络流的图 图中可能会有流量不平衡和流量>容量的情况存在 每调整一单位的流量/容量 需要一个单位的花费 问最少需要多少花费使得原图调整为正确(可行)的网络流 设当前边信息为(u,v,f, ...

  2. codeforces gym 100357 I (费用流)

    题目大意 给出一个或与表达式,每个正变量和反变量最多出现一次,询问是否存在一种方案使得每个或式中有且仅有一个变量的值为1. 解题分析 将每个变量拆成三个点x,y,z. y表示对应的正变量,z表示对应的 ...

  3. CodeForces 1187G Gang Up 费用流

    题解: 先按时间轴将一个点拆成100个点. 第一个点相当于第一秒, 第二个点相当于第二秒. 在这些点之间连边, 每1流量的费用为c. 再将图上的边也拆开. 将 u_i 向 v_i+1 建边. 将 v_ ...

  4. Codeforces 最大流 费用流

    这套题目做完后,一定要反复的看! 代码经常出现的几个问题: 本机测试超时: 1.init函数忘记写. 2.addedge函数写成add函数. 3.边连错了. 代码TLE: 1.前向星边数组开小. 2. ...

  5. Codeforces Gym 100002 E "Evacuation Plan" 费用流

    "Evacuation Plan" Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/10 ...

  6. Codeforces Gym 101190M Mole Tunnels - 费用流

    题目传送门 传送门 题目大意 $m$只鼹鼠有$n$个巢穴,$n - 1$条长度为$1$的通道将它们连通且第$i(i > 1)$个巢穴与第$\left\lfloor \frac{i}{2}\rig ...

  7. Codeforces 280D k-Maximum Subsequence Sum [模拟费用流,线段树]

    洛谷 Codeforces bzoj1,bzoj2 这可真是一道n倍经验题呢-- 思路 我首先想到了DP,然后矩阵,然后线段树,然后T飞-- 搜了题解之后发现是模拟费用流. 直接维护选k个子段时的最优 ...

  8. BZOJ 3836 Codeforces 280D k-Maximum Subsequence Sum (模拟费用流、线段树)

    题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=3836 (Codeforces) http://codeforces.com ...

  9. Codeforces 730I [费用流]

    /* 不要低头,不要放弃,不要气馁,不要慌张 题意: 给两行n个数,要求从第一行选取a个数,第二行选取b个数使得这些数加起来和最大. 限制条件是第一行选取了某个数的条件下,第二行不能选取对应位置的数. ...

随机推荐

  1. int (*p)[4] p 是二级指针 二维数组 二级指针 .xml

    pre{ line-height:1; color:#2f88e4; background-color:#e9ffff; font-size:16px;}.sysFunc{color:#3d7477; ...

  2. switch……case不能匹配字符串的方法 .xml

    pre{ line-height:1; color:#d1653c; background-color:#000000; font-size:16px;}.sysFunc{color:#566d68; ...

  3. redhat Enterprise Linux Server release 7.2(Maipo) 安装redis-stat

    项目需要在rh7.2安装redis-stat,各种编译不过.通过一步步跟踪编译错误日志发现时缺少各种开发库. 需要安装的库列表如下: zlib-devel openssl-devel readline ...

  4. IGF职业组比赛

    IGF职业组比赛 参赛资格: 面向亚太区所有独立游戏开发者(参见详细规则) 截止日期: 2015年7月20日 2015年IGF职业组七大奖项设置如下: * 最佳游戏(RMB20, 000) * 最佳移 ...

  5. ansible playbook最佳实践

    本篇主要是根据官方翻译而来,从而使简单的翻译,并没有相关的实验步骤,以后文章会补充为实验步骤,此篇主要是相关理论的说明,可以称之为中文手册之一,具体内容如下: Ansible playbooks最佳实 ...

  6. 【C#】Abstract和Virtual的区别

    一.Virtual方法(虚方法) virtual 关键字用于在基类中修饰方法.virtual的使用会有两种情况: 情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法.那么在对派生类 ...

  7. (转载)OC学习篇之---代理模式

    在前一篇文章我们介绍了OC中的协议的概念,这篇文章我们就来介绍一下OC中的代理模式,关于代理模式,如果还有同学不太清楚的话,就自己去补充知识了,这里就不做介绍了,这里只介绍OC中是如何实现代理模式的. ...

  8. effective c++:对象的赋值运算

    operator 中处理”自我赋值“ operator=操作符缺省情况下返回引用——TYPE& TYPE::operator=(const TYPE&),原因很简单,operator= ...

  9. Strider SSH Deploy配置

    登录需要ssh, ssh 免密码登录配置自行百度.shell里写成自己的需要的命令

  10. ios8 下请求读取通讯录权限 (网上众多资料漏下得一个坑)

    读取通讯录权限网上都有,不再叙述. 当第一次授权时用户假如拒绝授权, 第二次就无法再次弹出提示框授权. 刚开始时完全按照网上例子写的,第一次拒绝授权后,在设置里面无法找到对应的更改读取权限的选项. 后 ...