[国家集训队]航班安排 (最大费用最大流)

description

神犇航空有K架飞机,为了简化问题,我们认为每架飞机都是相同的。神犇航空的世界中有N个机场,以0…N-1编号,其中0号为基地机场,每天0时刻起飞机才可以从该机场起飞,并不晚于T时刻回到该机场。一天,神犇航空接到了M个包机请求,每个请求为在s时刻从a机场起飞,在恰好t时刻到达b机场,可以净获利c。设计一种方案,使得总收益最大。

Input
第一行,4个正整数N,M,K,T,如题目描述中所述;

以下N行,每行N个整数,描述一个N*N的矩阵t,t­i,j表示从机场i空载飞至机场j,需要时间ti,j;

以下N行, 每行N个整数,描述一个N*N的矩阵f,f­i,j表示从机场i空载飞至机场j,需要费用fi,j;

以下M行,每行5个整数描述一个请求,依次为a,b,s,t,c。

Output
仅一行,一个整数,表示最大收益。

Sample Input
2 1 1 10
0 5
5 0
0 5
5 0
0 1 0 5 10

Sample Output
5

Hint
数据规模及约定
对于10%的测试数据,K=1;
另有20%的测试数据,K=2;
对于全部的测试数据,N,M<=200,K<=10,T<=3000,ti,j<=200,fi,j<=2000,0<=a,b<N,0<=s<=t<=T,0<=c<=10000,ti,i=fi,i=0,ti,j<=ti,k+tk,j,fi,j<=fi,k+fk,j。

solution

在这里插入图片描述

将请求拆成两个点,之间的费用就是净收益ccc,流量为111,一个请求只完成一次
然后再根据时间限制判断能否将请求的起终点与源点汇点连边,流量infinfinf

000飞到请求起点的时间≤\le请求要求的起飞时间
从请求要求的结束时间➕从请求终点飞回000点时间≤T\le TT

但不一定是完成一个请求后立马飞回000点,或许直接飞往下一个请求的起点更优
所以还需要对请求之间进行两两建边

请求完成时刻➕飞到下一个请求的起点所有时间≤\le下一个请求的起飞时刻

最大化收益那就跑最大费用最大流

code

#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 205
#define maxm 100005
#define inf 0x3f3f3f3f
struct node {int a, b, s, t, c;
}Q[maxn];
struct Edge {int nxt, to, w, flow;
}edge[maxm << 1];
queue < int > q;
int n, m, K, T, st, ed, cnt, Time, cost;
int ti[maxn][maxn], w[maxn][maxn];
int dis[maxm], head[maxm], vis[maxm], pre[maxm];void addedge( int u, int v, int w, int flow ) {edge[cnt].nxt = head[u];edge[cnt].to = v;edge[cnt].w = w;edge[cnt].flow = flow;head[u] = cnt ++;
}bool spfa() {for( int i = 0;i <= ed;i ++ ) dis[i] = -inf, vis[i] = 0, pre[i] = -1;//memset(dis,-0x3f,sizeof(dis))无法初始化极小值 q.push( st );dis[st] = 0, vis[st] = 1;while( ! q.empty() ) {int u = q.front(); q.pop();vis[u] = 0;for( int i = head[u];~ i;i = edge[i].nxt ) {int v = edge[i].to;if( dis[v] < dis[u] + edge[i].w && edge[i].flow ) {dis[v] = dis[u] + edge[i].w;pre[v] = i;if( ! vis[v] ) {q.push( v );vis[v] = 1;}}}}return dis[ed] != -inf;
}void MCMF() {while( spfa() ) {int flow = inf;for( int i = pre[ed];~ i;i = pre[edge[i ^ 1].to] )flow = min( flow, edge[i].flow );for( int i = pre[ed];~ i;i = pre[edge[i ^ 1].to] ) {edge[i].flow -= flow;edge[i ^ 1].flow += flow;cost += edge[i].w * flow;}}
}int main() {memset( head, -1, sizeof( head ) );scanf( "%d %d %d %d", &n, &m, &K, &T );for( int i = 0;i < n;i ++ )for( int j = 0;j < n;j ++ )scanf( "%d", &ti[i][j] );for( int i = 0;i < n;i ++ )for( int j = 0;j < n;j ++ )scanf( "%d", &w[i][j] );for( int i = 1;i <= m;i ++ )scanf( "%d %d %d %d %d", &Q[i].a, &Q[i].b, &Q[i].s, &Q[i].t, &Q[i].c );st = 0, ed = ( m << 1 ) + 2;for( int i = 1;i <= m;i ++ ) {addedge( i << 1, i << 1 | 1, Q[i].c, 1 );addedge( i << 1 | 1, i << 1, -Q[i].c, 0 );if( Q[i].t + ti[Q[i].b][0] <= T ) {addedge( i << 1 | 1, ed, -w[Q[i].b][0], inf );addedge( ed, i << 1 | 1, w[Q[i].b][0], 0 );}else continue;if( ti[0][Q[i].a] <= Q[i].s ) {addedge( st + 1, i << 1, -w[0][Q[i].a], inf );addedge( i << 1, st + 1, w[0][Q[i].a], 0 );}for( int j = 1;j <= m;j ++ )if( Q[i].t + ti[Q[i].b][Q[j].a] <= Q[j].s ) {addedge( i << 1 | 1, j << 1, -w[Q[i].b][Q[j].a], inf );addedge( j << 1, i << 1 | 1, w[Q[i].b][Q[j].a], 0 );}}addedge( st, st + 1, 0, K );addedge( st + 1, st, 0, 0 );MCMF();printf( "%d", cost );return 0;
}

Dinic费用流版本

#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 205
#define maxm 100005
#define inf 0x3f3f3f3f
struct node {int a, b, s, t, c;
}Q[maxn];
struct Edge {int nxt, to, w, flow;
}edge[maxm << 1];
queue < int > q;
int n, m, K, T, st, ed, cnt = 1, Time, cost;
int ti[maxn][maxn], w[maxn][maxn];
int dis[maxm], head[maxm], vis[maxm];void addedge( int u, int v, int w, int flow ) {cnt ++;edge[cnt].nxt = head[u];edge[cnt].to = v;edge[cnt].w = w;edge[cnt].flow = flow;head[u] = cnt;
}bool spfa() {for( int i = 0;i <= ed;i ++ ) dis[i] = -inf, vis[i] = 0;//memset(dis,-0x3f,sizeof(dis))无法初始化极小值 q.push( st );dis[st] = 0, vis[st] = 1;while( ! q.empty() ) {int u = q.front(); q.pop();vis[u] = 0;for( int i = head[u];i;i = edge[i].nxt ) {int v = edge[i].to;if( dis[v] < dis[u] + edge[i].w && edge[i].flow ) {dis[v] = dis[u] + edge[i].w;if( ! vis[v] ) {q.push( v );vis[v] = 1;}}}}return dis[ed] != -inf;
}int dfs( int u, int cap ) {if( u == ed ) return cap;vis[u] = Time;int flow = 0;for( int i = head[u];i;i = edge[i].nxt ) {int v = edge[i].to;if( ( vis[v] != Time || v == ed ) && edge[i].flow && dis[v] == dis[u] + edge[i].w ) {int tmp = dfs( v, min( cap, edge[i].flow ) );if( ! tmp ) continue;edge[i].flow -= tmp;edge[i ^ 1].flow += tmp;flow += tmp;cap -= tmp;cost += tmp * edge[i].w;if( ! cap ) break;}}return flow;
}void Dinic() {while( spfa() ) {do {Time ++;dfs( st, inf );} while( vis[ed] == Time );}
}int main() {scanf( "%d %d %d %d", &n, &m, &K, &T );for( int i = 0;i < n;i ++ )for( int j = 0;j < n;j ++ )scanf( "%d", &ti[i][j] );for( int i = 0;i < n;i ++ )for( int j = 0;j < n;j ++ )scanf( "%d", &w[i][j] );for( int i = 1;i <= m;i ++ )scanf( "%d %d %d %d %d", &Q[i].a, &Q[i].b, &Q[i].s, &Q[i].t, &Q[i].c );st = 0, ed = ( m << 1 ) + 2;for( int i = 1;i <= m;i ++ ) {addedge( i << 1, i << 1 | 1, Q[i].c, 1 );addedge( i << 1 | 1, i << 1, -Q[i].c, 0 );if( Q[i].t + ti[Q[i].b][0] <= T ) {addedge( i << 1 | 1, ed, -w[Q[i].b][0], inf );addedge( ed, i << 1 | 1, w[Q[i].b][0], 0 );}else continue;if( ti[0][Q[i].a] <= Q[i].s ) {addedge( st + 1, i << 1, -w[0][Q[i].a], inf );addedge( i << 1, st + 1, w[0][Q[i].a], 0 );}for( int j = 1;j <= m;j ++ )if( Q[i].t + ti[Q[i].b][Q[j].a] <= Q[j].s ) {addedge( i << 1 | 1, j << 1, -w[Q[i].b][Q[j].a], inf );addedge( j << 1, i << 1 | 1, w[Q[i].b][Q[j].a], 0 );}}addedge( st, st + 1, 0, K );addedge( st + 1, st, 0, 0 );Dinic();printf( "%d", cost );return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317642.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

新数据革命:开源图形化数据引擎Hawk5发布

Hawk是一款开源图形化的爬虫和数据清洗工具&#xff0c;GitHub Star超过2k&#xff0c;前几代版本介绍如下&#xff1a;Hawk3: 终于等到你: 图形化开源爬虫Hawk 3发布!Hawk2: 120项优化: 超级爬虫Hawk 2.0重磅发布&#xff01;Hawk1: 如何从互联网采集海量数据&#xff1f;租房…

[TJOI2018]智力竞赛 (匈牙利)

description 题目描述 小豆报名参加智力竞赛&#xff0c;他带上了 n个好朋友作为亲友团一块来参加比赛。 比赛规则如下&#xff1a;一共有 m道题目&#xff0c;每个人都有 1 次答题机会&#xff0c;每次答题为选择一道题目回答&#xff0c;在回答正确后&#xff0c;可以从这个…

ASP.NET Core如何在ActionFilterAttribute里做依赖注入

点击蓝字关注我在ASP.NET Core里&#xff0c;我们可以使用构造函数注入很方便地对Controller&#xff0c;ViewComponent等部件做依赖注入。但是如何给过滤器ActionFilterAttribute也用上构造函数注入呢&#xff1f;问题我的博客系统里有个用来删除订阅文件缓存的ActionFilter&a…

[八省联考2018]劈配 (匈牙利)

description 一年一度的综艺节目《中国新代码》又开始了。Zayid 从小就梦想成为一名程序员&#xff0c;他觉得这是一个展示自己的舞台&#xff0c;于是他毫不犹豫地报名了。 轻车熟路的 Zayid 顺利地通过了海选&#xff0c;接下来的环节是导师盲选&#xff0c;这一阶段的规则…

助力苏州、星火相传,广苏两地微软技术俱乐部交流纪实

2019年1月19日时值二十四节气“大寒”前夕&#xff0c;江南水乡冬日的寒气盖不住苏州.NET开发者的热情&#xff0c;就在这一天苏州微软技术俱乐部成立了并举办了第一场大型的线下交流活动。星火相传2018年12月8日广州.NET微软技术俱乐部举办了恢复以来的第一场大型线下技术交流…

微软技术专家为您解读深度学习

随着阿尔法狗、无人驾驶、智能翻译的横空出世&#xff0c;“人工智能”这个已经存在60多年的词语&#xff0c;仿佛一夜之间重新成为热词。同时被科技圈和企业界广泛提及的还有“机器学习”“深度学习”“神经网络”…… 但如此喧嚣热烈的气氛之下&#xff0c;大部分人对这一领域…

「LibreOJ NOI Round #2」不等关系 (dp+NTT分治)

description 戳我看题目哦 solution 有一道非常相似的题目 一棵树&#xff0c;每条边限制两个端点的大小关系&#xff08;限制 a[u]>a[v]a[u]>a[v]a[u]>a[v] 或 a[u]<a[v]a[u]<a[v]a[u]<a[v]&#xff09; 求有多少种符合要求的排列aaa满足整棵树的限制。n…

PCB 机器学习(ML.NET)初体验实现PCB加投率预测

使用ML.NET建立PCB加投率模型对单一蚀刻工序进行加投率预测, 此实例为最简单预测&#xff0c;要想实现全流程加投率预测挑战难度还是挺大的&#xff0c;可以查看另一种关于大数据在PCB行业应用---加投率计算基本原理:PCB 加投率计算实现基本原理--K最近邻算法&#xff08;KNN&a…

潘淳的苏州.NET俱乐部成立有感!附我的录音

引言&#xff1a;今天是1月21日&#xff0c;我&#xff08;潘淳&#xff09;的生日&#xff0c;两天前刚刚过了他&#xff08;苏俱&#xff09;的生日&#xff0c;微软技术俱乐部&#xff08;苏州&#xff09;在苏州微软正式成立。作为大会活动的策划者和活动发起者之一&#x…

十年 IT 老兵带你通过案例学架构,附C#代码

技术大会上的分享大多高大上&#xff0c;亿级流量、超大型研发团队&#xff0c;虽然值得借鉴&#xff0c;但由于应用场景与研发资源的差异&#xff0c;一般企业并不容易落地。其实&#xff0c;中小型研发团队在IT行业还是占大多数&#xff0c;他们在技术架构方面的问题较多&…

浅谈一致性Hash原理及应用

在讲一致性Hash之前我们先来讨论一个问题。问题&#xff1a;现在有亿级用户&#xff0c;每日产生千万级订单&#xff0c;如何将订单进行分片分表&#xff1f;小A&#xff1a;我们可以按照手机号的尾数进行分片&#xff0c;同一个尾数的手机号写入同一片/同一表中。大佬&#xf…

如何定义开发完成?(Definition of Done)

最近在拜读郑晔的10x程序员工作法&#xff0c;收益良多&#xff0c;文中提出一个概念叫DoD&#xff08;Definition of Done&#xff09;给我的感触颇深。这让我联想到实际工作过程中&#xff0c;经常遇到的扯皮、争吵等各种场景&#xff0c;其实就和这个DoD分不开。一、场景描述…

【正睿2021寒假省选第二轮集训 day 1】串 (后缀自动机+记忆化)

description 定义一个字符串的子串是这个字符串的某个连续区间的字符组成的串。比如&#xff0c;“djq"的子串是"d”,“j”,“q”,“dj”,“jq”,和"djq"。 定义F(a,b)为最长在字符串bb中至少出现一次的字符串a的子串&#xff0c;例如&#xff1a; F(“d…

欧拉筛法的应用

[数论]-----欧拉筛法的应用 文章目录1.求1~n之间的所有质数2.求1~n之间所有自然数的欧拉函数φ&#xff08;x&#xff09;3.求1~n之间的每个数的因子个数详细推导&#xff1a;代码&#xff1a;4.求1~n之间每个数的因数和详细的推导&#xff1a;代码&#xff1a;筛法求莫比乌斯函…

全新尝试|ComponentOne WinForm和.NET Core 3.0

在微软 Build 2018 开发者大会上&#xff0c;.NET 团队公布了 .NET Core 的下一个主要版本 .NET Core 3.0 的规划蓝图&#xff1a;.NET Core 3将开始支持 Windows 桌面应用程序&#xff0c;包括 Windows Form、Windows Presentation Framework&#xff08;WPF&#xff09;和UWP…

[bzoj3625][Codeforces Round #250]小朋友和二叉树 (生成函数)

description 我们的小朋友很喜欢计算机科学&#xff0c;而且尤其喜欢二叉树。 考虑一个含有n个互异正整数的序列c[1],c[2],…,c[n]。如果一棵带点权的有根二叉树满足其所有顶点的权值都在集合{c[1],c[2],…,c[n]}中&#xff0c;我们的小朋友就会将其称作神犇的。并且他认为&am…

H - Tunnel Warfare HDU - 1540

H - Tunnel Warfare HDU - 1540 题意&#xff1a; n个数顺序排列&#xff0c;左右数相连&#xff0c; 现在有三个操作&#xff1a; 1.摧毁一个位置上的数 2.回复上一次摧毁的数 3.查询包含该位置的最长连续区间长度 题解&#xff1a; 有两个方法&#xff0c;第一个是区间的…

2019年1月已到,Java 8 要收费了吗?

根据此前开源中国发起的 Java 版本使用调查&#xff0c;国内的 Java 主力版本仍是 Java 8&#xff0c;有近 70% 的用户表示仍在使用 Java 8。所以对于「Java 8 是否要收费」这个问题&#xff0c;十分有必要阐述清楚&#xff0c;以消除不必要的恐慌。首先要明确一点&#xff0c;…

[NOI2007] 货币兑换 (dp+李超树维护凸包)

description 小Y最近在一家金券交易所工作。该金券交易所只发行交易两种金券&#xff1a;A纪念券&#xff08;以下简称A券&#xff09;和 B纪念券&#xff08;以下简称B券&#xff09;。每个持有金券的顾客都有一个自己的帐户。金券的数目可以是一个实数。每天随着市场的起伏波…

[ZJOI2008]树的统计

[ZJOI2008]树的统计 题意&#xff1a; 题解&#xff1a; 树链剖分模板题&#xff0c;好久没打都忘了 代码&#xff1a; #include <algorithm> #include <cstdio> #include <cstring> #define lc o << 1 #define rc o << 1 | 1 const int max…