知识点
分层图用于求在单源最短路径中,建立多层相同或相似的图, 并在图与图之间进行连边,可以实现 两种性质的图 之间的 转移,或是 图与图 之间 有限制的转移。换句话说,就是求图中存在 k 条可缩短的路径或边权可为 0 的路径最值问题。
因为对于原图的 n 个点来说,都可以选择下一条边是否赋予权值为0,或使权值缩小,那么我们可以将图画出k+1层。
个人觉得分层图最难理解的,就是建边的过程。
建边核心代码:
for(register int i = 1;i <= m;++ i)
{
int x,y,z;
cin >> x >> y >> z;
add(x,y,z),add(y,x,z);
for(register int j = 1;j <= k;++ j)
{
//将其他图对应的边连接起来
add(j * n + x,j * n + y,z);
add(j * n + y,j * n + x,z);
//两张图的连接点,即可以改变的值,可能为0,也可能为n/2等边权
add((j - 1) * n + x,j * n + y,0);
add((j - 1) * n + y,j * n + x,0);
}
}
!!注意:每建一层图,对应的点的位置需要向后移动n个,需要特别注意 数组范围
模板题:
思路:其实在题目中就已经点明这是一道求单源最短路径的题目,最保险的算法就是Dijkstra + 优先队列。在建图的部分能体现分层图,将上下两层之间连上正常边的权值一半大小的边即可,该题的难点就在于分层图的建边。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
int n,m,k;
const int maxn=1e7+5,INF=0x3f3f3f3f;
struct node{
int to,next,w;
}edge[maxn<<1];
int head[maxn],num=