版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38013346/article/details/82313662
Description
分层图最短路,就是在分层图上解决最短路问题。
主要是应用于变化的最短路问题,问题常表现为一个最短路问题上加一些手脚,如减小一些边权,改变一些连接,但事先又不知道,或可以自由选择改变哪个边,最终求最短路等等。由于无法知道改变了那些边,所以用到分层图思想。
$1.一种解决方法是多开一维记录状态,多开的维度记录状态的种类数即为分层数。 $
连接的基础上,在相邻层中间加一些要求的变化边,通常是单向的(保证从每一层到下一层不再回来),再跑最短路。
Input
Output
最短路径长度
Solution
$1.一种解决方法是多开一维记录状态,多开的维度记录状态的种类数即为分层数。 $
Codes
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
typedef long long ll;
struct Edge {
int to;
ll cost;
Edge(){}
Edge(int _t,ll _c) {to = _t;cost = _c;}
};
vector<Edge> ways[maxn];
struct qNode {
int x,y;
ll cost;
qNode(){}
qNode(int _t,int _k,ll _c) {x = _t;y = _k;cost = _c;}
bool operator < (const qNode &a) const {
return cost > a.cost;
}
};
int n,m,k,from,to;
bool vis[maxn][15];
ll dist[maxn][15];
inline void init() {
for(int i=0;i<maxn;i++) ways[i].clear();
}
inline void addedge(int u,int v,ll c) {
ways[u].push_back(Edge(v,c));
}
ll solve(int from,int to) {
memset(vis,0,sizeof(vis));
memset(dist,0x3f,sizeof(dist));
//printf("%lld\n",dist[0][0]);
priority_queue<qNode> qu;
while(!qu.empty()) qu.pop();
dist[from][0] = 0;
qu.push(qNode(from,0,dist[from][0]));
qNode now;
Edge tmp;
while(!qu.empty()) {
now = qu.top(); qu.pop();
int u = now.x,step = now.y;
vis[u][step] = true;
for(int i=0;i<ways[u].size();i++) {
tmp = ways[u][i];
int v = tmp.to;ll cost = tmp.cost;
if(!vis[v][step] && dist[v][step] > dist[u][step] + cost) {
dist[v][step] = dist[u][step] + cost;
qu.push(qNode(v,step,dist[v][step]));
}
/// 对下一层进行松弛
if(step == k) continue;
if(!vis[v][step+1] && dist[v][step+1] > dist[u][step]) {
dist[v][step+1] = dist[u][step];
qu.push(qNode(v,step+1,dist[v][step+1]));
}
}
}
return dist[to][k];
}
int main()
{
int caset;scanf("%d",&caset);
while(caset--) {
scanf("%d%d%d",&n,&m,&k);
init();
// scanf("%d%d",&from,&to);
ll c;
for(int i=0,u,v;i<m;i++) {
scanf("%d%d%lld",&u,&v,&c);
addedge(u,v,c);
}
ll ans = solve(1,n);
printf("%lld\n",ans);
}
return 0;
}