分层图解决的一些最短路问题
关于分层图
340. 通信线路 - AcWing题库
在郊区有 NN 座通信基站,PP 条 双向 电缆,第 ii 条电缆连接基站 AiAi 和 BiBi。
特别地,11 号基站是通信公司的总站,NN 号基站位于一座农场中。
现在,农场主希望对通信线路进行升级,其中升级第 ii 条电缆需要花费 LiLi。
电话公司正在举行优惠活动。
农产主可以指定一条从 11 号基站到 NN 号基站的路径,并指定路径上不超过 KK 条电缆,由电话公司免费提供升级服务。
农场主只需要支付在该路径上剩余的电缆中,升级价格最贵的那条电缆的花费即可。
求至少用多少钱可以完成升级。
输入格式
第 11 行:三个整数 N,P,KN,P,K。
第 2..P+12..P+1 行:第 i+1i+1 行包含三个整数 Ai,Bi,LiAi,Bi,Li。
输出格式
包含一个整数表示最少花费。
若 11 号基站与 NN 号基站之间不存在路径,则输出 −1−1。
数据范围
0≤K<N≤10000≤K<N≤1000,
1≤P≤100001≤P≤10000,
1≤Li≤10000001≤Li≤1000000
输入样例:
5 7 1
1 2 5
3 1 4
2 4 8
3 2 3
5 2 9
3 4 7
4 5 6
输出样例:
4
解法一:
由于选择k条边免费,所以建立k层分层图,每条边与他同层临点建边不会改变他的连通性,k条免费的边就相当于每层之间的边的边权为0,在k层之间跑最短路就相应的对应上原题意
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <map>
#include <set>
using namespace std;
#define mst(x, y) memset(x, y, sizeof x);
#define X first
#define Y second
#define int long long
#define FAST ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
const int N = 1e6 + 10, M = 2e7 + 10, INF = 0x3f3f3f3f, EPS = 1e-8;
typedef pair<int, int> PII;
int n, p, k;
int h[N], e[N], w[N], ne[N], idx;
int d[N];
bool st[N];
void add(int a, int b, int c) // 添加一条边a->b,边权为c
{e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}
void dijkstra()
{mst(d, 0x3f);d[1] = 0;priority_queue<PII, vector<PII>, greater<PII>> heap;heap.push({0, 1});while (heap.size()){auto t = heap.top();heap.pop();int id = t.Y, dist = t.X;if (st[id])continue;st[id] = true;for (int i = h[id]; ~i; i = ne[i]){int j = e[i], v = max(w[i], d[id]);if (d[j] > v){d[j] = v;heap.push({d[j], j});}}}
}
signed main()
{FAST;mst(h, -1);cin >> n >> p >> k;for (int i = 1; i <= p; i++){int a, b, c;cin >> a >> b >> c;add(a, b, c), add(b, a, c);for (int j = 0; j < k; j++){add(a + j * n, b + (j + 1) * n, 0);add(b + j * n, a + (j + 1) * n, 0);add(a + (j + 1) * n, b + (j + 1) * n, c);add(b + (j + 1) * n, a + (j + 1) * n, c);}}for (int i = 1; i <= k; i++){add(i * n, (i + 1) * n, 0);}dijkstra();if (d[n * (k + 1)] >= 1e6+10)cout << "-1" << endl;elsecout << d[n * (k + 1)] << endl;return 0;
}
解法二:
340. 通信线路 - AcWing题库
I-旅行_2022河南萌新联赛第(三)场:河南大学 (nowcoder.com)
根据题意:每个邻点之间建立需要核酸与不需要核酸的两种情况的两种边,最后只会有两种情况(上一个点到n号点需要核酸,边权为w,or上一个点到n号点不需要核酸,边权为w+x)
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <map>
#include <set>
using namespace std;
#define mst(x, y) memset(x, y, sizeof x);
#define X first
#define Y second
#define int long long
#define FAST ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
const int N = 200010, M = 4 * N, INF = 0x3f3f3f3f, EPS = 1e-8;
typedef pair<int, int> PII;
int n, m, x;
int h[N], e[M], w[M], ne[M], idx;
int d[N];
bool st[N];
void add(int a, int b, int c) // 添加一条边a->b,边权为c
{e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}void dijkstra()
{mst(d, 0x3f);d[1] = 0;priority_queue<PII, vector<PII>, greater<PII>> heap;heap.push({0, 1});while (heap.size()){auto t = heap.top();heap.pop();int id = t.Y, dist = t.X;if (st[id])continue;st[id] = true;for (int i = h[id]; ~i; i = ne[i]){int j = e[i];if (d[j] > d[id] + w[i]){d[j] = d[id] + w[i];heap.push({d[j], j});}}}
}
signed main()
{FAST;mst(h, -1);cin >> n >> m >> x;for (int i = 1; i <= m; i++){int a, b, c;cin >> a >> b >> c;add(a, b + n, c + x), add(a + n, b, c);add(b, a + n, c + x), add(b + n, a, c);}dijkstra();cout << min(d[n], d[2 * n]) << endl; // d[n]代表最后到达n号点是需要核酸, d[2*n]代表最后到达n号点不需要核酸return 0;
}
2953. 飞行路线 - AcWing题库
同理与上题类似,建立k层分层图相当于k-1层之间边权都为0
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <map>
#include <set>
using namespace std;
#define mst(x, y) memset(x, y, sizeof x);
#define X first
#define Y second
#define int long long
#define FAST ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
const int N = 2e5+10, M = 5e6+10, INF = 0x3f3f3f3f, EPS = 1e-8;
typedef pair<int, int> PII;
int n, m, k;
int s, t;
int h[N], e[M], w[M], ne[M], idx;
int d[N];
bool st[N];
void add(int a, int b, int c) // 添加一条边a->b,边权为c
{e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}
void dijkstra()
{mst(d, 0x3f);d[s] = 0;priority_queue<PII, vector<PII>, greater<PII>> heap;heap.push({0, s});while (heap.size()){auto t = heap.top();heap.pop();int id = t.Y, dist = t.X;if (st[id])continue;st[id] = true;for (int i = h[id]; ~i; i = ne[i]){int j = e[i];if (d[j] > d[id] + w[i]){d[j] = d[id] + w[i];heap.push({d[j], j});}}}
}signed main()
{FAST;cin >> n >> m >> k;cin >> s >> t;mst(h, -1);for (int i = 1; i <= m; i++){int a, b, c;cin >> a >> b >> c;add(a, b, c), add(b, a, c);for (int j = 1; j <= k; j++){add(a + j * n, b + j * n, c);add(b + j * n, a + j * n, c);add(a + (j - 1) * n, b + j * n, 0);add(b + (j - 1) * n, a + j * n, 0);}}for (int i = 1; i <= k; i++){add(t + (i - 1) * n, t + i * n, 0);}dijkstra();cout << d[n * k + t] << endl;return 0;
}
341. 最优贸易 - AcWing题库
建三层图,第二层代表买,第三层代表卖;
同层之间不进行买卖,边权都为0;
相邻层的相同点连通表示买卖的权值,买为负权,卖为正权,第一层与第二层之间为负权边,第二层与都三层之间为正权边;
最后SPFA跑一遍最长路,(可以将第一层与第二层建正权,第二层与第三层建负权,跑最短路,-d[3*n]是答案),d[3*n]即为答案;
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <map>
#include <set>
using namespace std;
#define mst(x, y) memset(x, y, sizeof x);
#define X first
#define Y second
#define int long long
#define FAST ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
const int N = 200010, M = 4 * N, INF = 0x3f3f3f3f, EPS = 1e-8;
typedef pair<int, int> PII;
int n, m;
int val[N];
int h[N], e[M], w[M], ne[M], idx;
int d[N];
bool st[N];
void add(int a, int b, int c) // 添加一条边a->b,边权为c
{e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}
void SPFA() // 求1号点到n号点的最短路距离,如果从1号点无法走到n号点则返回-1
{memset(d, -INF, sizeof d);d[1] = 0;queue<int> q;q.push(1);st[1] = true;while (q.size()){int t = q.front();q.pop();st[t] = false;for (int i = h[t]; i != -1; i = ne[i]){int j = e[i];if (d[j] < d[t] + w[i]){d[j] = d[t] + w[i];if (!st[j]){q.push(j);st[j] = true;}}}}
}
signed main()
{FAST;mst(h, -1);cin >> n >> m;for (int i = 1; i <= n; i++)cin >> val[i];for (int i = 1; i <= m; i++){int a, b, c;cin >> a >> b >> c;if (c == 1){add(a, b, 0);add(a + n, b + n, 0);add(a + 2 * n, b + 2 * n, 0);}else if (c == 2){add(a, b, 0), add(b, a, 0);add(a + n, b + n, 0), add(b + n, a + n, 0);add(a + 2 * n, b + 2 * n, 0), add(b + 2 * n, a + 2 * n, 0);}}for (int i = 1; i <= n; i++){add(i, i + n, -val[i]);add(i + n, i + 2 * n, val[i]);}SPFA();if (d[3 * n] >= 0)cout << d[3 * n] << endl;elsecout << "0" << endl;return 0;
}
分层图解决的一些最短路问题相关推荐
- 分层图最短路问题小记
分层图最短路问题小记 本质还是最短路问题只是开多了一维数组表示层次 模板: #include<bits/stdc++.h> using namespace std; typedef lon ...
- BZOJ2662[BeiJing wc2012]冻结——分层图最短路
题目描述 "我要成为魔法少女!" "那么,以灵魂为代价,你希望得到什么?" "我要将有关魔法和奇迹的一切,封印于卡片之中„„" ...
- Bzoj 2662: [BeiJing wc2012]冻结 dijkstra,堆,分层图,最短路
2662: [BeiJing wc2012]冻结 Time Limit: 3 Sec Memory Limit: 128 MB Submit: 647 Solved: 348 [Submit][S ...
- CF990G GCD Counting(树上莫比乌斯反演,分层图,并查集)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Problem 给定一棵点带权无根树,对于每个 k∈[1,2×105]k\in[1,2\times10 ...
- 洛谷 P4011 孤岛营救问题【最短路+分层图】
题外话:昨夜脑子昏沉,今早一调试就过了...错误有:我忘记还有墙直接穿墙过...memset初始化INF用错了数...然后手残敲错一个状态一直过不了样例...要是这状态去比赛我简直完了......or ...
- 洛谷 P1073 最优贸易 (分层图状态转移+SPFA,求最长路径;另附某dalao的超短代码:暴力+动规)
题目链接1 题目链接2 另附某dalao的超短代码:暴力+动规 P1073 最优贸易 题目描述 C国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市. 任意两个城市之间最多只有 ...
- 【算法练习】CodeVs1391 伊吹萃香(分层图最短路)
题意 在幻想乡,伊吹萃香是能够控制物体密度的鬼王.因为能够控制密度,所以萃香能够制造白洞和黑洞,并可以随时改变它们.某一天萃香闲着无聊,在妖怪之山上设置了一些白洞或黑洞,由于引力的影响,给妖怪们带来了 ...
- 三个指标怎么做分层图_分层性能指标以及在哪里找到它们
三个指标怎么做分层图 Hierarchical machine learning models are one top-notch trick. As discussed in previous po ...
- Android实现无序树形结构图,类似思维导图和级联分层图(无序,随机位置)
参考文章: 利用递归算法.堆栈打造一个android可擦除思维导图 用SurfaceView实现级联分层图(粗略篇) 效果图打头阵: 这些和亲戚关系图谱,或者思维导图类似,最近公司的医疗项目也用到了这 ...
- HGANMDA:用于miRNA与疾病关联预测的分层图注意力网络(Molecular Therapy)
HGANMDA:Hierarchical graph attention network for miRNA-disease association prediction https://www.sc ...
最新文章
- 2020年五大云计算预测
- Java全角、半角字符的关系以及转换
- 胜任素质--哈佛大学教授麦克里兰 (McClelland)有效地预测外交官实际工作业绩的人员选拔方法...
- 【转】Service Intent must be explicit的解决方法
- linux xshell上传文件夹,XShell上传文件到Linux服务器上
- 【STM32】窗口看门狗
- mysql 随机选取一条记录
- GitHub重大更新即将加入免费软件包管理服务;钉钉社区因出现违规内容将停更整改一个月;Uber上市,定价为45美元……...
- mysql挪到小数点位置_mysql数据库迁移到另一个硬盘上
- SpringBoot FK-关联表查询(二)
- 基于IdentityServer4的单点登录——项目基本结构与流程
- python能不能在win10系统中使用_python在win10下可以用吗
- php练习——打印半金字塔、金字塔、空心金字塔、菱形、空心菱形
- explict关键字
- C++递归方法实现全排列
- Fortan写出数据到CSV文件中
- stata 自相关专题【计量经济系列(五)】
- 去除xp桌面图标阴影
- 为什么要学数学、语文?还有英语!
- 【下载】Step7 V5.4 中文版【绝对能安装使用】
热门文章
- python lol脚本_Python爬虫获取op.gg英雄联盟英雄对位胜率的源码
- 移动通信概述-架构篇
- 10006---当当架构部张亮:从码农到大牛,技术与心境的双重提升
- CEVA-DSP构成
- 手机计算机如何用科学计算法,手机计算器开根号怎么按(万能科学计算器在线使用方法)...
- 虚拟机的服务器显示全屏,虚拟机怎么实现全屏显示
- python学习笔记六
- c语言中等于号和大于号的优先级,C 读书笔记之 关系运算符重载 大于号 小于号 等于号==...
- mybatis 的大于号 小于号 大于等于 小于等于
- AT4565 Beginning