最短路 SPFA()

拜拜、爱过 提交于 2020-01-30 01:26:03

  SPFA是用队列处理Bellman-Ford算法,效率很高。但他并不稳定。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int inf = 0x3f3f3f3f;
 5 const int num = ???;
 6 struct edge{
 7     int from, to, w;//边:起点from(其实没有用到),终点to,权值(距离)w
 8     edge(int a, int b, int c){from=a; to=b; w=c;} 
 9 };
10 vector<edge>e[num];//第i个节点连接的所有边 
11 int n, m;
12 int dis[num];//从规定起点到点i的距离 
13 int pre[num];//记录路径 
14 
15 //打印路径 
16 void print_path(int s, int t){
17     if(s == t){printf("%d",s);    return ;}
18     print_path(s, pre[t]);
19     printf("->%d",t); 
20 }
21 
22 int spfa(int s){
23     bool inq[num];//标记节点i是否在队列中
24     int neg[num];//判断负圈 
25     //初始化 
26     for(int i=1; i<=n; i++){
27         neg[i] = 0;
28         dis[i] = inf;
29         inq[i] = false;
30     } 
31     neg[s] = 1;
32     //
33     queue<int>q;
34     q.push(s);
35     inq[s] = true;//s进队 
36     //
37     while(!q.empty()){
38         int u = q.front();
39         q.pop();
40         inq[u] = false;//s出队
41         
42         for(int i=0; i<e[u].size(); i++){//检查节点u连接的所有边 
43             int v = e[u][i].to, w = e[u][i].w;
44             if(dis[u] + w < dis[v]){//起点->u->v的距离 < 起点->v的距离 
45                 dis[v] = dis[u] + w;
46                 pre[v] = u;
47                 if(!inq[v]){//如果v不在队列则插入 
48                     inq[v] = true;
49                     q.push(v);
50                     neg[v]++;
51                     if(neg[v] > n)    return 1;//v的更新次数超过节点个数,则说明存在负圈 
52                 }
53             }
54         } 
55     }
56     //print_path(s,?);
57     return 0;
58 }
59 
60 int main(){
61     while(~scanf("%d %d", &n, &m) && n && m){
62         for(int i=1; i<=n; i++)        e[i].clear();
63         while(m--){
64             int a, b, c;
65             scanf("%d %d %d", &a, &b, &c);
66             e[a].push_back(edge(a,b,c));
67             e[b].push_back(edge(b,a,c));
68         }
69         spfa(1);//规定1为起点 
70     } 
71     return 0;
72 }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!