【最大费用最大流】【Codeforces】164C - Machine Programming
2012-12-22 02:05
525 查看
题目来源 :http://www.codeforces.com/problemset/problem/164/C
题目大意 :有N(1 <= N <= 1000)个任务要用K(1 <= K <= 50)台机器完成,每个任务持续一段时间Si ~ Si + Ti - 1,每个任务可以获利Ci,(1 ≤ Si , Ti ≤ 109 , 1 ≤ Ci ≤ 106 ) 。每台机器同一时间内只能处理至多1个任务。满足以上限制条件,求这K台机器能取得的最大利润是多少?
题目解析 : 从贪心角度看,如果存在多个时间不相交的任务,那么这些任务只需要1台机器去完成。因此,每台机器处理的就是这样的一系列不相交的任务。那么对于时间相交的任务,就需要用多台机器去完成。一共有K台机器,那么问题转化为求K条不相交任务集合,使得总获利最大。
本题和《线性规划与网络流24题 -- 最长 k 可重区间集》建模方法一模一样。将所有任务的时间离散化,编号为1..L。设立源点S和汇点T,建立有向边S->1,容量为K,费用为0;(表示最多有K条不相交任务集合)建立有向边L->T,容量为INF, 费用为0;建立有向边I(1 ~ L - 1)->I + 1,容量为INF,费用为0;对于每个任务的时间Si 和 Si + Ti - 1 所对应的编号 X和Y,建立有向边X->Y,容量为1,费用为-Ci。求最小费用最大流。
模型的理解 : 每个任务限制容量为1,表示只被完成1次,然后获利就是这条边的费用,写成负数是为了求最小费用,实际原问题属于最大费用最大流。并且以时间为端点,不相交的任务可以用同一台机器去完成,相交的任务只能用多台机器去完成。
另外题目要求的是路径,而不是最大费用那个值。因此要把费用为负数的满流边记录下来,最后输出。
代码如下 :
题目大意 :有N(1 <= N <= 1000)个任务要用K(1 <= K <= 50)台机器完成,每个任务持续一段时间Si ~ Si + Ti - 1,每个任务可以获利Ci,(1 ≤ Si , Ti ≤ 109 , 1 ≤ Ci ≤ 106 ) 。每台机器同一时间内只能处理至多1个任务。满足以上限制条件,求这K台机器能取得的最大利润是多少?
题目解析 : 从贪心角度看,如果存在多个时间不相交的任务,那么这些任务只需要1台机器去完成。因此,每台机器处理的就是这样的一系列不相交的任务。那么对于时间相交的任务,就需要用多台机器去完成。一共有K台机器,那么问题转化为求K条不相交任务集合,使得总获利最大。
本题和《线性规划与网络流24题 -- 最长 k 可重区间集》建模方法一模一样。将所有任务的时间离散化,编号为1..L。设立源点S和汇点T,建立有向边S->1,容量为K,费用为0;(表示最多有K条不相交任务集合)建立有向边L->T,容量为INF, 费用为0;建立有向边I(1 ~ L - 1)->I + 1,容量为INF,费用为0;对于每个任务的时间Si 和 Si + Ti - 1 所对应的编号 X和Y,建立有向边X->Y,容量为1,费用为-Ci。求最小费用最大流。
模型的理解 : 每个任务限制容量为1,表示只被完成1次,然后获利就是这条边的费用,写成负数是为了求最小费用,实际原问题属于最大费用最大流。并且以时间为端点,不相交的任务可以用同一台机器去完成,相交的任务只能用多台机器去完成。
另外题目要求的是路径,而不是最大费用那个值。因此要把费用为负数的满流边记录下来,最后输出。
代码如下 :
#include <iostream> #include <climits> #include <utility> #include <vector> #include <deque> #include <map> #include <algorithm> #define rep(i, x) for (int i = 1; i <= x; i ++) #define rept(i, x) for (int i = 0; i <= x; i ++) #define tr(i, x) for (typeof(x.begin()) i = x.begin(); i != x.end(); i ++) #define all(x) x.begin(), x.end() #define pb push_back #define ppf pop_front() #define mp make_pair using namespace std; const int Maxn = 2001, INF = INT_MAX; typedef pair <int, int> kk; typedef pair <kk, int> kkk; struct edge { int v, c, w; edge* next, * op; edge(int _v, int _c, int _w, edge* _next) : v(_v), c(_c), w(_w), next(_next) {} }* E[Maxn], * PE[Maxn]; bool hash[Maxn]; int S, T, N, K, X[Maxn], Y[Maxn], W[Maxn], P[Maxn]; vector <int> Dist, Co; deque <int> Q; map <int, int> Name; map <kkk, int> Task; void Print() { rept(i, T) for (edge* j = E[i]; j; j = j -> next) { if (j -> w < 0 && j -> c == 0) Task[mp(mp(i, j -> v), j -> w)] ++; } int Count = 0; rep(i, N) { if (i != 1) cout << " "; int x = Name[X[i]], y = Name[Y[i]]; kkk tmp = mp(mp(x, y), -W[i]); if (Task[tmp] > 0) { cout << 1; Task[tmp] --; } else cout << 0; } cout << endl; } void Augment() { int add = INF; for (int i = T; i != S; i = P[i]) { if (PE[i] -> c < add) add = PE[i] -> c; } for (int i = T; i != S; i = P[i]) { PE[i] -> c -= add; PE[i] -> op -> c += add; } } bool SPFA() { Dist.assign(T + 1, INF); Dist[S] = 0; Q.pb(S); while (Q.size()) { int i = Q.front(); Q.ppf; hash[i] = false; for (edge* j = E[i]; j; j = j -> next) { int v = j -> v; if (j -> c && Dist[i] + j -> w < Dist[v]) { Dist[v] = Dist[i] + j -> w; P[v] = i; PE[v] = j; if (!hash[v]) { hash[v] = true; Q.pb(v); } } } } return Dist[T] != INF; } void SPFAFlow() { while (SPFA()) Augment(); } inline void edgeAdd(int x, int y, int c, int w) { E[x] = new edge(y, c, w, E[x]); E[y] = new edge(x, 0, -w, E[y]); E[x] -> op = E[y]; E[y] -> op = E[x]; } void Graph() { S = 0; T = Co.size() + 1; edgeAdd(S, 1, K, 0); edgeAdd(Co.size(), T, K, 0); rep(i, Co.size() - 1) edgeAdd(i, i + 1, INF, 0); rep(i, N) edgeAdd(Name[X[i]], Name[Y[i]], 1, -W[i]); } void Init() { cin >> N >> K; rep(i, N) { cin >> X[i] >> Y[i] >> W[i]; Y[i] += X[i]; Co.pb(X[i]); Co.pb(Y[i]); } sort(all(Co)); Co.erase(unique(all(Co)), Co.end()); tr(i, Co) Name[* i] = i - Co.begin() + 1; } int main() { Init(); Graph(); SPFAFlow(); Print(); return 0; }
相关文章推荐
- Codeforces 164C 费用流
- CodeForces 164C Machine Programming(费用流)
- [无源汇最大费用可行流 差分费用流] Codeforces 717G Bubble Cup 9 - Finals G. Underfail
- Codeforces 818G. Four Melodies 最大费用最大流
- hdu 2686 Matrix && hdu 3367 Matrix Again (最大费用最大流)
- CodeForces 682E Alyona and Triangles【最大三角形 旋转卡壳or迭代】
- 百度之星初赛第二场C题-费用流求最大权匹配
- codeforces 717 G. Underfail(费用流,好题)
- SDUT 2414 An interesting game(最大费用流)
- 二分图最大权匹配(费用流做法)
- ZOJ 3904 Beer Problem 最大费用最大流
- [bzoj1834][ZJOI2010] 网络扩容 最大流 费用流
- BZOJ3130: [Sdoi2013]费用流[最大流 实数二分]
- poj 2516 最小费用最大流
- POJ 3680 Intervals (拆点 || 离散) && 最大费用流
- 【HDU 3376 Matrix Again】网络流 & 拆点 & 最大费用最大流
- hdoj 2246 Interesting Housing Problem 【最大费用最大流 or KM算法】
- POJ--Kaka's Matrix Travels【最大费用最大流 && 经典建图 && 好题】
- hdu 6118 度度熊的交易计划 (最小费用最大流
- [ACM模板]MFMC最小费用最大流