P4452 [国家集训队]航班安排

题目传送门

解题思路:

感觉题面让人有很多误解,就是说有k架飞机在0点从0号机场起飞,在t时刻返回机场,给出空载飞行的时间和花费以及m个包机请求的花费和起始时间和终止时间,想要得到净利润最大,显然是个费用流,对于每个询问拆成两个点,点之间连一条流量为1,花费为这次请求的c,由于从0号机场起飞,如果满足0+从0号机场飞到该次请求的机场a的时间<=请求任务开始的时间s,那么建一条流量为inf,费用为-从0号机场飞到该次请求的机场a的花费,同样如果满足该次请求的t+该次请求的b机场飞到0号机场的时间<=t,也建一条流量为inf,费用为-从该次请求的b号机场飞到0号机场的花费,最后对于每个询问,是否能与其他询问连边,如果一个询问的结束时间t+从该询问的b机场到另一个询问的a机场的时间<=另一个询问的开始时间s,那么也能连上一条流量为inf,花费为-空载飞行的花费的边,最后由于有k架飞机,再建个超级源点流到0号机场的点,流量为k,花费为0即可

代码:

代码写得和解题思路有点出入,主要是点位序号我为了方便把0号机场变成了1号

#include <bits/stdc++.h>
using namespace std;
/* freopen("k.in", "r", stdin);
freopen("k.out", "w", stdout); */
// clock_t c1 = clock();
// std::cerr << "Time:" << clock() - c1 <<"ms" << std::endl;
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define de(a) cout << #a << " = " << a << endl
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
#define ls ((x) << 1)
#define rs ((x) << 1 | 1)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef vector<int, int> VII;
#define inf 0x3f3f3f3f
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MAXN = 1e5 + 7;
const ll MAXM = 1e6 + 7;
const ll MOD = 1e9 + 7;
const double eps = 1e-6;
const double pi = acos(-1.0);
inline int read_int()
{
char c;
int ret = 0, sgn = 1;
do
{
c = getchar();
} while ((c < '0' || c > '9') && c != '-');
if (c == '-')
sgn = -1;
else
ret = c - '0';
while ((c = getchar()) >= '0' && c <= '9')
ret = ret * 10 + (c - '0');
return sgn * ret;
}
inline ll read_ll()
{
char c;
ll ret = 0, sgn = 1;
do
{
c = getchar();
} while ((c < '0' || c > '9') && c != '-');
if (c == '-')
sgn = -1;
else
ret = c - '0';
while ((c = getchar()) >= '0' && c <= '9')
ret = ret * 10 + (c - '0');
return sgn * ret;
} struct edge
{
int to, capacity, cost, rev;
edge() {}
edge(int to, int _capacity, int _cost, int _rev) : to(to), capacity(_capacity), cost(_cost), rev(_rev) {}
};
struct Min_Cost_Max_Flow
{
int V, H[MAXN + 5], dis[MAXN + 5], PreV[MAXN + 5], PreE[MAXN + 5];
vector<edge> G[MAXN + 5];
void Init(int n)
{
V = n;
for (int i = 0; i <= V; ++i)
G[i].clear();
}
void Add_Edge(int from, int to, int cap, int cost)
{
G[from].push_back(edge(to, cap, cost, G[to].size()));
G[to].push_back(edge(from, 0, -cost, G[from].size() - 1));
}
int Min_cost_max_flow(int s, int t, int f, int &flow)
{
int res = 0;
fill(H, H + 1 + V, 0);
while (f)
{
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
fill(dis, dis + 1 + V, inf);
dis[s] = 0;
q.push(pair<int, int>(0, s));
while (!q.empty())
{
pair<int, int> now = q.top();
q.pop();
int v = now.second;
if (dis[v] < now.first)
continue;
for (int i = 0; i < G[v].size(); ++i)
{
edge &e = G[v][i];
if (e.capacity > 0 && dis[e.to] > dis[v] + e.cost + H[v] - H[e.to])
{
dis[e.to] = dis[v] + e.cost + H[v] - H[e.to];
PreV[e.to] = v;
PreE[e.to] = i;
q.push(pair<int, int>(dis[e.to], e.to));
}
}
}
if (dis[t] == inf)
break;
for (int i = 0; i <= V; ++i)
H[i] += dis[i];
int d = f;
for (int v = t; v != s; v = PreV[v])
d = min(d, G[PreV[v]][PreE[v]].capacity);
f -= d;
flow += d;
res += d * H[t];
for (int v = t; v != s; v = PreV[v])
{
edge &e = G[PreV[v]][PreE[v]];
e.capacity -= d;
G[v][e.rev].capacity += d;
}
}
return res;
}
int Max_cost_max_flow(int s, int t, int f, int &flow)
{
int res = 0;
fill(H, H + 1 + V, 0);
while (f)
{
priority_queue<pair<int, int>> q;
fill(dis, dis + 1 + V, -inf);
dis[s] = 0;
q.push(pair<int, int>(0, s));
while (!q.empty())
{
pair<int, int> now = q.top();
q.pop();
int v = now.second;
if (dis[v] > now.first)
continue;
for (int i = 0; i < G[v].size(); ++i)
{
edge &e = G[v][i];
if (e.capacity > 0 && dis[e.to] < dis[v] + e.cost + H[v] - H[e.to])
{
dis[e.to] = dis[v] + e.cost + H[v] - H[e.to];
PreV[e.to] = v;
PreE[e.to] = i;
q.push(pair<int, int>(dis[e.to], e.to));
}
}
}
if (dis[t] == -inf)
break;
for (int i = 0; i <= V; ++i)
H[i] += dis[i];
int d = f;
for (int v = t; v != s; v = PreV[v])
d = min(d, G[PreV[v]][PreE[v]].capacity);
f -= d;
flow += d;
res += d * H[t];
for (int v = t; v != s; v = PreV[v])
{
edge &e = G[PreV[v]][PreE[v]];
e.capacity -= d;
G[v][e.rev].capacity += d;
}
}
return res;
}
};
Min_Cost_Max_Flow MCMF;
PII p[305][305];
struct quest
{
int a, b, s, t, c;
} q[MAXN + 5];
int main()
{
int n = read_int(), m = read_int(), k = read_int(), t = read_int();
MCMF.Init((m << 1 | 1) + 1);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
p[i][j].first = read_int();
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
p[i][j].second = read_int();
for (int i = 1; i <= m; i++)
{
q[i].a = read_int(), q[i].b = read_int(), q[i].s = read_int(), q[i].t = read_int(), q[i].c = read_int();
q[i].a++, q[i].b++;
}
for (int i = 1; i <= m; i++)
{
MCMF.Add_Edge(i << 1, i << 1 | 1, 1, q[i].c);
if (p[1][q[i].a].first <= q[i].s)
MCMF.Add_Edge(1, i << 1, inf, -p[1][q[i].a].second);
if (p[q[i].b][1].first + q[i].t <= t)
MCMF.Add_Edge(i << 1 | 1, (m << 1 | 1) + 1, inf, -p[q[i].b][1].second);
for (int j = 1; j <= m; j++)
{
if (i == j)
continue;
if (q[i].t + p[q[i].b][q[j].a].first <= q[j].s)
MCMF.Add_Edge(i << 1 | 1, j << 1, inf, -p[q[i].b][q[j].a].second);
}
}
int st = 0, ed = (m << 1 | 1) + 1;
MCMF.Add_Edge(st, 1, k, 0);
int flow = 0;
int ans = MCMF.Max_cost_max_flow(st, ed, inf, flow);
printf("%d\n", ans);
return 0;
}

P4452 [国家集训队]航班安排(最大费用最大流)的更多相关文章

  1. BZOJ5120 [2017国家集训队测试]无限之环 费用流

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ5120 题意概括 原题挺简略的. 题解 本题好难. 听了任轩笛大佬<国家队神犇>的讲课才 ...

  2. BZOJ 5120: [2017国家集训队测试]无限之环(费用流)

    传送门 解题思路 神仙题.调了一个晚上+半个上午..这道咋看咋都不像图论的题竟然用费用流做,将行+列为奇数的点和偶数的点分开,也就是匹配问题,然后把一个点复制四份,分别代表这个点的上下左右接头,如果有 ...

  3. 洛谷 - P4452 - 航班安排 - 费用流

    https://www.luogu.org/problemnew/show/P4452 又一道看题解的费用流. 注意时间也影响节点,像题解那样建边就少很多了. #include<bits/std ...

  4. BZOJ2040[2009国家集训队]拯救Protoss的故乡——模拟费用流+线段树+树链剖分

    题目描述 在星历2012年,星灵英雄Zeratul预测到他所在的Aiur行星在M天后会发生持续性暴雨灾害,尤其是他们的首都.而Zeratul作为星灵族的英雄,当然是要尽自己最大的努力帮助星灵族渡过这场 ...

  5. 【BZOJ 2039】 2039: [2009国家集训队]employ人员雇佣 (最小割)

    2039: [2009国家集训队]employ人员雇佣 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1511  Solved: 728 Descri ...

  6. 洛谷——P3918 [国家集训队]特技飞行

    P3918 [国家集训队]特技飞行 神犇航空开展了一项载客特技飞行业务.每次飞行长N个单位时间,每个单位时间可以进行一项特技动作,可选的动作有K种,每种动作有一个刺激程度Ci.如果连续进行相同的动作, ...

  7. BZOJ 2039: [2009国家集训队]employ人员雇佣

    2039: [2009国家集训队]employ人员雇佣 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1369  Solved: 667[Submit ...

  8. BZOJ 2038: [2009国家集训队]小Z的袜子(hose) [莫队算法]【学习笔记】

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 7687  Solved: 3516[Subm ...

  9. BZOJ 2038: [2009国家集训队]小Z的袜子(hose)

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 7676  Solved: 3509[Subm ...

随机推荐

  1. Kali之msf简单的漏洞利用

    1.信息收集 靶机的IP地址为:192.168.173.136 利用nmap工具扫描其开放端口.系统等 整理一下目标系统的相关信息 系统版本:Windows server 2003 开放的端口及服务: ...

  2. MicroPython TPYBoard v702实现HTTP应用功能

    [Micropython]TPYBoard v702 HTTP应用功能 转载请注明文章来源,更多教程可自助参考docs.tpyboard.com,QQ技术交流群:157816561,公众号:Micro ...

  3. C#录制视频

    这是一个使用C#语言制作的录制框架,支持录制桌面,多屏,声音,摄像头,某个应用程序的界面 1.安装 使用此框架需要安装扩展包Kogel.Record,可以Nuget上搜索 或者使用Nuget命令 In ...

  4. 2020年Java程序员应该学习的10大技术

    对于Java开发人员来说,最近几年的时间中,Java生态诞生了很多东西.每6个月更新一次Java版本,以及发布很多流行的框架,如Spring 5.Spring Security 5和Spring Bo ...

  5. 你对Java泛型的理解够深入吗?

    泛型 泛型提供了一种将集合类型传达给编译器的方法,一旦编译器知道了集合元素的类型,编译器就可以对其类型进行检查,做类型约束. 在没有泛型之前: /** * 迭代 Collection ,注意 Coll ...

  6. .net core 开车记:Data Protection Key 过期问题与登录页面访问慢

    K8s 船还没修好,.net core 车又出了问题,开着 k8s 豪华邮轮.飚着 .net core 极品飞车的好事真是多磨. 自从我们用上 .net core ,就一直被 .net core 的一 ...

  7. yarn详细入门教程(转载)

    简介Yarn 是 Facebook, Google, Exponent 和 Tilde 开发的一款新的 JavaScript 包管理工具.就像我们可以从官方文档了解那样,它的目的是解决这些团队使用 n ...

  8. 测开大佬告诉你:如何5分钟快速创建restful风格的API接口-使用django restframework框架

    一.思考❓❔ 1.创建API接口难吗? 软件测试工程师: 只测过API接口, 从没创建过 应该需要掌握一门后端开发语言和后端开发框架吧!? 脑容量有限,想想就可怕 2.如何创建API接口呢? 使用Dj ...

  9. .NET Core 3 WPF MVVM框架 Prism系列之模块化

    本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的应用程序的模块化 前言  我们都知道,为了构成一个低耦合,高内聚的应用程序,我们会分层,拿一个WPF程序来说,我们通过MVVM模式 ...

  10. 【转】提升你的Java应用性能:改善数据处理

    提升你的Java应用性能:改善数据处理 作者:贾小骏  发布于07月26日 10:17 许多应用程序在压力测试阶段或在生产环境中都会遇到性能问题.如果我们看一下性能问题背后的原因,会发现很多是由数据处 ...