我会说这是太神给NOIP入门的同学出的题么?!表示今天刚做,虽然以前学过,但这是第一次写,要注意建边的时候只需要建一层的就可以了,然后每次跑spfa的时候,看看能不能跑到下一层。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#define maxn 200010
#define inf 1000000000
#define maxm 200010
using namespace std;
int next[maxm],to[maxm],len[maxm],head[maxn];
int dis[maxn],q[maxn];
bool vis[maxn];
int n,m,T,k,s,t,num;
int cal(int x,int y)
{
return x+y*n;
}
void addedge(int x,int y,int z)
{
num++;to[num]=y;len[num]=z;next[num]=head[x];head[x]=num;
}
void spfa()
{
for (int i=0;i<=cal(n,k);i++) dis[i]=inf;
int l=0,r=1;
dis[s]=0;q[1]=s;vis[s]=1;
while (l!=r)
{
l++;if (l==maxn) l=0;
int x=q[l];
int d=x/n,t=x%n;
for (int p=head[t];p;p=next[p])
{
if (dis[cal(to[p],d)]>dis[cal(t,d)]+len[p])
{
dis[cal(to[p],d)]=dis[cal(t,d)]+len[p];
if (!vis[cal(to[p],d)])
{
vis[cal(to[p],d)]=1;
r++;if (r==maxn) r=0;
q[r]=cal(to[p],d);
}
}
if (d<k && dis[cal(t,d)]<dis[cal(to[p],d+1)])
{
dis[cal(to[p],d+1)]=dis[cal(t,d)];
if (!vis[cal(to[p],d+1)])
{
vis[cal(to[p],d+1)]=1;
r++;if (r==maxn) r=0;
q[r]=cal(to[p],d+1);
}
}
}
vis[x]=0;
}
}
int main()
{
scanf("%d%d%d%d%d",&n,&m,&k,&s,&t);
for (int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
addedge(x,y,z);addedge(y,x,z);
}
spfa();
printf("%d\n",dis[cal(t,k)]);
return 0;
}