解析:
分层最短路:
分层图: 有多个平行的图
模型: 在一个正常的图上进行k次决策,对于每次决策都不影响图的结构,只影响目前的状态或代价。一般将决策前的状态和决策后的状态连接一条权值为决策代价的边,表示付出该代价后,可以转移状态
建图有两种方法:
1.建图直接建k+1层图
2.多开一维记录信息
本篇只介绍第一种方法
我们建k+1层图。然后有边的两个点,多建一条到下一层边权为0的单向边,如果走了这条边就表示用了一次机会。
答案就是3,3+n,3+2n,中的最小值。
本篇引用:https://blog.csdn.net/sugarbliss/article/details/86551050
#include<bits/stdc++.h>
#pragma GCC optimize(3,"Ofast","inline")
#define x first
#define y second
using namespace std;
typedef pair<int,int>PII ;
int n,m,k,a,b,c;
int s,t;
const int M=5e4+1000;
int h[M*4*11],ne[M*4*11],e[M*4*11],idx,w[M*4*11];
int dist[M*4*11];
bool vis[M*4*11];
int read()
{
int x=0;char c=getchar();
while(!isdigit(c))
{
c=getchar();
}
while(isdigit(c))
{
x=x*10+(c^48);
c=getchar();
}
return x;
}
void add(int u,int v,int c)
{
e[idx]=v;w[idx]=c;ne[idx]=h[u];h[u]=idx++;
}
void dij()
{
priority_queue<PII,vector<PII> ,greater<PII> > q;
for(int i=1;i<=n*(k+1);i++) dist[i]=0x3f3f3f3f;
q.push({0,s});
dist[s]=0;
while(q.size())
{
auto t=q.top();
q.pop();
int ver=t.y;
if(vis[ver]) continue;
vis[ver]=true;
for(int i=h[ver];~i;i=ne[i])
{
int j=e[i];
if(dist[j]>dist[ver]+w[i])
{
dist[j]=dist[ver]+w[i];
q.push({dist[j],j});
}
}
}
}
int main()
{
memset(h,-1,sizeof h);
n=read();m=read();k=read();
s=read();t=read();
s=s+1;t=t+1;
while(m--)
{
a=read();b=read();c=read();
a=a+1;b=b+1;
for(int i=0;i<=k;i++)
{
add(a+i*n,b+i*n,c);add(b+i*n,a+i*n,c);
if(i!=k)
{
add(a+i*n,b+(i+1)*n,0);
add(b+i*n,a+(i+1)*n,0);
}
}
}
dij();
int ans=0x3f3f3f3f;
for(int i=0;i<=k;i++) ans=min(ans,dist[t+i*n]);
printf("%d\n",ans);
}