蓝桥杯 algo_5 最短路 (bellman,SPFA)

问题描述

给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路(顶点从1到n编号)。

输入格式

第一行两个整数n, m。

接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边。

输出格式
共n-1行,第i行表示1号点到i+1号点的最短路。
样例输入
3 3
1 2 -1
2 3 -1
3 1 2
样例输出
-1
-2
由于有负边,所以Dijkstra算法无法使用,而Floyd算法的效率太低,容易超时,所以使用Bellman(SPFA)来计算这道题
这是我的ac代码:
 1 #include<iostream>
 2 #include<string.h>
 3 #include<queue>
 4 using namespace std;
 5 struct node{
 6     int e,next,val;
 7 }edge[200010];
 8 int M=0,N,head[20010],m;
 9 bool v[20010];
10 void add(int s,int e,int val){
11     edge[++M].e=e;
12     edge[M].val=val;
13     edge[M].next=head[s];
14     head[s]=M;
15 }
16 int lowCost[20010];
17 void bellman(int s){
18     for(int i=1;i<=N;i++){
19         lowCost[i]=99999999;
20         v[i]=0;
21     }
22     queue<int> q;
23     lowCost[s]=0;
24     q.push(s);
25     v[s]=1;
26     while(!q.empty()){
27         int u=q.front();q.pop();
28         v[u]=0;
29         for(int i=head[u];i!=-1;i=edge[i].next){
30             int no=edge[i].e;
31             int val=edge[i].val;
32             if(lowCost[u]+val<lowCost[no]&&!v[no]){
33                 lowCost[no]=lowCost[u]+val;
34                 v[no]=1;
35                 q.push(no);
36             }
37         }
38     }
39 }
40 int main(){
41     cin>>N>>m;
42     int s,e,v;
43     memset(head,-1,sizeof(head));
44     for(int i=1;i<=m;i++){
45         cin>>s>>e>>v;
46         add(s,e,v);
47     }
48     bellman(1);
49     for(int i=2;i<=N;i++){
50         cout<<lowCost[i]<<endl;
51     }
52     return 0;
53 }
原文地址:https://www.cnblogs.com/yifan2016/p/5269239.html