题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5644

题意:

每天都有p[i]个飞行员进行阅兵,飞行员只工作一天。

m个休假公式,花费tt[i]元让飞行员在休假ss[i]天后回来上班。

可以花费Q元雇佣新的飞行员,但是直到P天后才能上班。

分析:

首先某一天雇佣的飞行员有三种可能:

1.原来就有的

  • 从s到第一天的结点连一条容量为k,费用为0的边。
  • 从第i天向第i+1天连一条容量为INF,费用为0的边。

2.新雇佣的:

  • 新雇佣的飞行员必须在P天后使用,所以在s和第P天的结点连一条容量为INF,费用为Q的边。

3.放假回来的:

(这里就不知道应该怎么处理了。)

其实仔细想,将每一天的结点都拆成两个,其中一个表示正常上班的情况,另一个用于表示飞行员休假回来上班的情况。也就是说:

  • 在第x[i]和第y[i+tt]结点之间连一条容量为INF,费用为ss的边,表示第i+tt天用的是第i天开始休假tt天后回来的飞行员的情况。

最后从s到x[i]建一条容量为p[i],费用为0的边,在y[i]到t同样建一条容量为p[i],费用为0的边,然后跑一下最小费用流判断是否满流就好啦~!

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
const int maxm = 505;
const int INF = 0x3f3f3f3f;
int s, t, tot, all = 0;
int dist[maxm], prevv[maxm], preve[maxm], head[maxm];
bool in[maxm];
int maxflow;
struct Edge{ int from, to, next, cap, cost;}edge[maxm<<2];
void add_edge(int from, int to, int cap, int cost)
{
edge[tot].to = to;
edge[tot].from = from;
edge[tot].cap = cap;
edge[tot].cost = cost;
edge[tot].next = head[from];
head[from] = tot++;
edge[tot].to = from;
edge[tot].from = to;
edge[tot].cap = 0;
edge[tot].cost = -cost;
edge[tot].next = head[to];
head[to] = tot++;
}
bool spfa(int s, int t)
{
memset(dist, 0x3f, sizeof(dist));
memset(in, false, sizeof(in));
queue<int>q;
q.push(s);
in[s] = true;
dist[s]=0;
while(!q.empty()){
int u = q.front();q.pop();
in[u] = false;
for(int i = head[u]; i != -1; i = edge[i].next){
Edge e = edge[i];
if(e.cap >0 && dist[e.to] > dist[u] + e.cost){
dist[e.to] = dist[u] + e.cost;
prevv[e.to] = u, preve[e.to] = i;
if(!in[e.to]){
in[e.to] = true;
q.push(e.to);
}
}
}
}
if(dist[t] == INF) return false;
return true;
}
int MCMF(int s, int t)
{
int flow = 0, cost = 0;
while(spfa(s, t)){
int d = INF;
for(int i = t; i != s; i = prevv[i]){
d = min(d, edge[preve[i]].cap);
}
flow += d;
cost += dist[t] * d;
for(int i = t; i != s; i = prevv[i]){
edge[preve[i]].cap -= d;
edge[preve[i]^1].cap += d;
}
}
maxflow = flow;
return cost;
}
int main (void)
{
int T;scanf("%d",&T);
while(T--){
tot = 0;
memset(head, -1, sizeof(head));
int n, k; scanf("%d%d",&n, &k);
int s = 0, t = 2 * n + 1;
add_edge(s, n + 1, k, 0);
int p, ss, tt;
int all = 0;
for(int i = 1; i <= n; i++){
scanf("%d", &p);
all += p;
add_edge(s, i, p, 0);
add_edge(i + n, t, p, 0);
}
for(int i = 1; i < n; i++)
add_edge(i + n, i + n +1, INF, 0); int m, P, Q;
scanf("%d%d%d",&m, &P, &Q);
for(int i = P; i <= n; i++)
add_edge(s, i + n, INF, Q);
for(int i = 0; i < m; i++){
scanf("%d%d",&ss, &tt);
for(int j = 1; j <= n - tt; j++)
add_edge(j, n + j + tt, INF, ss);
} int res =MCMF(s, t);
if(maxflow != all) printf("No solution\n");
else printf("%d\n",res);
}
}

其实建图还是挺难想的。。。。

HDU 5644 King's Pliot【费用流】的更多相关文章

  1. HDU 5644 King's Pilots 费用流

    King's Pilots 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5644 Description The military parade w ...

  2. HDU 3667 Transportation(网络流之费用流)

    题目地址:HDU 3667 这题的建图真是巧妙...为了保证流量正好达到k.须要让每一次增广到的流量都是1,这就须要把每一条边的流量都是1才行.可是每条边的流量并非1,该怎么办呢.这个时候能够拆边,反 ...

  3. 【进阶——最小费用最大流】hdu 1533 Going Home (费用流)Pacific Northwest 2004

    题意: 给一个n*m的矩阵,其中由k个人和k个房子,给每个人匹配一个不同的房子,要求所有人走过的曼哈顿距离之和最短. 输入: 多组输入数据. 每组输入数据第一行是两个整型n, m,表示矩阵的长和宽. ...

  4. HDU 3488--Tour(KM or 费用流)

    因为每个点只能经过一次 所以考虑拆点 这题有坑,有重边.. KM算法 把一个点拆成入点和出点 入点在X部,出点在Y步. 如果u,v之间有路径,就在X部的u点连接Y部的v点 求完美匹配. 当完美匹配的时 ...

  5. HDU - 5406 CRB and Apple (费用流)

    题意:对于给定的物品,求两个在高度上单调不递增,权值上单调不递减的序列,使二者长度之和最大. 分析:可以用费用流求解,因为要求长度和最大,视作从源点出发的流量为2的费用流,建负权边,每个物品只能取一次 ...

  6. HDU 5644 (费用流)

    Problem King's Pilots (HDU 5644) 题目大意 举办一次持续n天的飞行表演,第i天需要Pi个飞行员.共有m种休假计划,每个飞行员表演1次后,需要休假Si天,并提供Ti报酬来 ...

  7. hdu 1853 Cyclic Tour 最小费用最大流

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1853 There are N cities in our country, and M one-way ...

  8. Going Home HDU - 1533 费用流

    http://acm.hdu.edu.cn/showproblem.php?pid=1533 给一个网格图,每两个点之间的匹配花费为其曼哈顿距离,问给每个的"$m$"匹配到一个&q ...

  9. Tour HDU - 3488 有向环最小权值覆盖 费用流

    http://acm.hdu.edu.cn/showproblem.php?pid=3488 给一个无源汇的,带有边权的有向图 让你找出一个最小的哈密顿回路 可以用KM算法写,但是费用流也行 思路 1 ...

随机推荐

  1. .net 字符串和JSON格式的互换

    近期又做了个问卷调查,问卷调查一次性要保存一二十个题目和答案!所以嘞,博主为了偷懒,就直接把答卷内容保存成了Json格式! 好处当然是很多啦! 只需一个字段就能保存整个答卷的内容! 想想都刺激!哈哈~ ...

  2. ASP.Net 控件

    简单控件 Label -作用是显示文字,编译后元素是Span 1.文本类 边框: BorderColor 边框颜色 BordersTyle 边框样式 BorderWidth 边框粗细 Literal- ...

  3. 解决 图片在div中等比例缩放问题 (未解决:图片比例小于盒子模型时不会自动填充)

    如题,该方案仅支持对图片等比例缩放.本文附件地址:https://files.cnblogs.com/files/john69-/background-Img.rar <!DOCTYPE htm ...

  4. Rxjava2的学习与总结

    博客地址:https://luhaoaimama1.github.io/2017/07/31/rxjava/

  5. 1、QQ装机部落---腾讯软件

    亲,赚钱快人一步,我给你推荐QQ装机部落!大品牌,口碑好,知名软件,绿色无毒,每天结算,回报高!到这里注册:http://zjbl.qq.com/#/?invid=476058088 返利网邀请码立即 ...

  6. jQuery radio 选中提示

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. Python3.0 调用HTMLTestRunner生成的报告中不能显示用例中print函数的输出

    官方原生的HTMLTestRunner.py支持python2.0版本,python3.0版本的使用需要做一些修改: Python3调用HTMLTestRunner执行用例生成测试报告中,不能正常显示 ...

  8. OpenMP入门教程(一)

    什么是OpenMP Open Multi-Processing的缩写,是一个应用程序接口(API),可用于显式指导多线程.共享内存的并行性. 在项目程序已经完成好的情况下不需要大幅度的修改源代码,只需 ...

  9. CAD交互绘制圆弧(com接口)

    在CAD设计时,需要绘制圆弧,用户可以在图面点圆弧起点,圆弧上的一点和圆弧的终点,这样就绘制出圆弧. 主要用到函数说明: _DMxDrawX::DrawArc2 由圆弧上的三点绘制一个圆弧.详细说明如 ...

  10. java线程学习2

    sleep  变为阻塞态  但不释放锁  休眠指定毫秒时间 yield  变为就绪态  可能立即被执行  也可能不立即被执行 join   插队  暂停当前执行的线程  让调用join的线程先执行 线 ...