分层图最短路,每层正常建图,相邻两层间建w/2的边。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
queue<int> q;
struct node
{
int from;
int to;
int w;
int next;
}edge[3000005];
int dis[3005];bool vis[3005];
int n,m,k,head[3005],tot,ans=2100000000;
void add(int u,int v,int w)
{
edge[tot].from=u;
edge[tot].to=v;
edge[tot].w=w;
edge[tot].next=head[u];
head[u]=tot++;
}
void spfa()
{
q.push(1);
dis[1]=0;
while(!q.empty())
{
int x=q.front();vis[x]=0;
q.pop();
for(int i=head[x];i!=-1;i=edge[i].next)
{
if(dis[edge[i].to]>dis[x]+edge[i].w)
{
dis[edge[i].to]=dis[x]+edge[i].w;
if(!vis[edge[i].to])
q.push(edge[i].to),vis[edge[i].to]=1;
}
}
}
}
int main()
{
memset(head,-1,sizeof(head));
memset(dis,0x7f7f7f7f,sizeof(dis));
scanf("%d%d%d",&n,&m,&k);
int u,v,w;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
for(int j=0;j<=k;j++)
{
add(j*n+u,j*n+v,w);
add(j*n+v,j*n+u,w);
}
for(int j=0;j<k;j++)
{
add(j*n+u,(j+1)*n+v,w>>1);
add(j*n+v,(j+1)*n+u,w>>1);
}
}
spfa();
//for(int i=1;i<=(k+1)*n;i++)
//printf("%d ",dis[i]);
for(int i=1;i<=k+1;i++)
ans=min(ans,dis[i*n]);
printf("%d",ans);
}