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

数据规模与约定:
对于10%的数据,n = 2,m = 2。
对于30%的数据,n <= 5,m <= 10。
对于100%的数据,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保证从任意顶点都能到达其他所有顶点。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <stdio.h>
#include <queue>
#include <string.h>
 
#define Infinite 210000000
#define ListEndFlag  -1
 
int  number_vertex;
int  number_edge;
 
int  dist[20010];
int  head[20010];
struct {
     int  to, w, next;
}edge[200010];
 
void  SPFA()
{
     // 用于标识顶点是否在队列中
     bool  isAlreadyInQueue[20010];
 
     // 初始化数据
     for  ( int  i = 2; i <= number_vertex; i++)
     {
         dist[i] = Infinite;
         isAlreadyInQueue[i] =  false ;
     }
 
     dist[1] = 0;
     isAlreadyInQueue[1] =  true ;
 
     std::queue< int > q;
     q.push(1);
 
     while  (q.empty() ==  false )
     {
         const  int  x = q.front();
 
         for  ( int  i = head[x]; i != ListEndFlag; i = edge[i].next)
         {
             const  int  y = edge[i].to;
             const  int  w = edge[i].w;
 
             if  (dist[x] + w < dist[y])
             {
                 dist[y] = dist[x] + w;
 
                 if  (isAlreadyInQueue[y] ==  false )
                 {
                     q.push(y);
                     isAlreadyInQueue[y] =  true ;
                 }
             }
         }
 
         q.pop();
         isAlreadyInQueue[x] =  false ;
     }
}
 
int  main()
{
     // 1. 读取顶点数,边数
     scanf ( "%d%d" , &number_vertex, &number_edge);
 
     // 2. 设置 flag
     memset (head, ListEndFlag,  sizeof (head));
 
     // 3. 读取边
     for  ( int  i = 1; i <= number_edge; i++)
     {
         int  x, y, w;
         scanf ( "%d%d%d" , &x, &y, &w);
 
         edge[i].to   = y;
         edge[i].w    = w;
         edge[i].next = head[x];
 
         head[x]      = i;
     }
 
     // 4. 执行 SPFA
     SPFA();
 
     // 5. 输出结果
     for  ( int  i = 2; i <= number_vertex; i++)
     {
         printf ( "%d\n" , dist[i]);
     }
 
     return  0;
}

转载于:https://www.cnblogs.com/night-ride-depart/p/5093479.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值