题目链接:

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. Partial(部分方法,局部方法),virtual(虚方法),abstract(抽象方法)

    Partial 部分方法顾明思议是方法的一部分,不完整的,在ide编译时候,会将所有部分方法加载到一起统一编译,如果分部方法没有被实现,编译器就不会.对他们进行编译. 局部类型的限制 (1) 局部类型 ...

  2. Spark学习之Spark调优与调试(7)

    Spark学习之Spark调优与调试(7) 1. 对Spark进行调优与调试通常需要修改Spark应用运行时配置的选项. 当创建一个SparkContext时就会创建一个SparkConf实例. 2. ...

  3. 51全志R58平台Android4.4下Camera的HAL层修改

    51全志R58平台Android4.4下Camera的HAL层修改 2018/11/7 15:20 版本:V1.0 开发板:SC5806 1.系统编译: (略) 2.全志R58平台Android4.4 ...

  4. 全志R58平台调通s5k5eya(RAW+MIPI)

    全志R58平台调通s5k5eya(RAW+MIPI) 2017/5/31 10:30 版本:V1.1 1.前期使用的是s5k5eyx的ISP的固件/tuning 文件 Y:\s5k5eya_r58_d ...

  5. Rxjava2的学习与总结

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

  6. VUE 入坑系列 一 事件

    html代码 <div id="app"> <button v-on:click="counter += 1">加1</butto ...

  7. Protostuff序列化和反序列化

    序列化和反序列化是在应对网络编程最常遇到的问题之一. 序列化就是将Java Object转成byte[]:反序列化就是将byte[]转成Java Object. 这里不介绍JDK serializab ...

  8. http升级https改造方案

    一.解决方案 1.httpClient请求https版蓝鲸接口 (1).原理 https与http最大的区别在于SSL加密传输协议的使用.在自己写的JAVA HttpClient程序,想手动验证证书, ...

  9. vue获取dom元素高度的方法

    获取高度: <div ref="自定义名称" > </div>要在钩子mounted里面dom结构生成后去获取dom的高度,宽度,修改样式等操作!!! mo ...

  10. (转)淘淘商城系列——KindEditor富文本编辑器的使用

    http://blog.csdn.net/yerenyuan_pku/article/details/72809794 通过上文的学习,我们知道了怎样解决KindEditor富文本编辑器上传图片时的浏 ...