输入,n,m,n表示n条路径,m指m个地点
输入n条路径信息a,b,c(a,b指两个相连的地点,c指路径长度)
SPFA 在形式上和广度(宽度)优先搜索非常类似,不同的是bfs中一个点出了队列就不可能重新进入队列,但是SPFA中一个点可能在出队列之后再次被放入队列,也就是一个点改进过其它的点之后,过了一段时间可能本身被改进(重新入队),于是再次用来改进其它的点,这样反复迭代下去
#include <cstdio>
#include <cstring>
#include <string>
#include <set>
#include <cmath>
#include <iostream>
#include <stack>
#include <queue>
#include <map>
#include <vector>
#include <algorithm>
//const long long mod=2147493647;
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
using namespace std;
#define N 30005
#define inf 0x3f3f3f3f
int vis[N],dis[N];
int head[N];
struct node
{//se[]是一个链表储存点和边的信息
int u,v,w,next;
}se[N];
int cnt;
void add(int x,int y,int z)
{
// se[cnt].u=x;
// se[cnt].v=y;
// se[cnt].w=z;
// se[cnt].next=head[x];
se[cnt]=(node){x,y,z,head[x]};
head[x]=cnt++;
}
void init()
{
cnt=0;
mem(head,-1);
mem(vis,0);
mem(dis,inf);
}
void spfa(int s)
{
queue<int>q;
q.push(s);
vis[s]=1;//vis[i]=1表示i点在队列q中,反之不在
dis[s]=0;//dis[i]表示i点到源点的最短距离
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];i!=-1;i=se[i].next)
{
int v=se[i].v;
int w=se[i].w;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
if(!vis[v])
{
q.push(v);
vis[v]=1;
}
}
}
}
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
init();
for(int i=0;i<n;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
spfa(1);
printf("%d\n",dis[m]);
}
/*
in
5 5
1 2 20
2 3 30
3 4 20
4 5 20
1 5 100
out
90
*/