spfa模板

 1 //spfa在正权边题目容易被卡,所以正权边的情况下还是用dijkstra吧
 2 //spfa比dijkstra的优点是可以判负环,处理负权边
 3 //spfa的时间复杂度为(O(|V||E|))
 4 //spfa是求单元最短路
 5 //spfa在最小费用最大流中常用
 6 
 7 #include<cstdio>
 8 #include<cstring>
 9 #include<cmath>
10 #include<queue>
11 #include<algorithm>
12 #include<iostream>
13 using namespace std;
14 typedef long long ll;
15 #define endl '\n'
16 const int maxn = 10100;//最大顶点数
17 const int maxm = 500500;//最大边数
18 const int inf = 0x3f3f3f3f;
19 struct edge{
20     int to,nxt,w;
21 }e[maxn];
22 
23 int using_v[maxn],using_times[maxn];//入队的点和点的入队次数
24 int head[maxn],dis[maxn];
25 int cnt=0;
26 int n,m;    //n个点m条边
27 
28 void addedge(int u,int v,int w){
29     e[cnt].to=v;
30     e[cnt].w=w;
31     e[cnt].nxt=head[u];
32     head[u]=cnt++;
33 }
34 
35 int spfa(int start){
36     queue<int>q;
37     dis[start]=0;       //起始点离自己的dis为0
38     using_v[start]=1;   //起始点标记
39     q.push(start);      //入队
40     while( !q.empty()){
41         int top=q.front();  
42         q.pop();            
43         using_v[top]=0;     
44         if( using_times[top]>n ) return 0;  //存在负环
45         for(int i=head[top];~i;i=e[i].nxt){
46             if( dis[e[i].to]>dis[top]+e[i].w){
47                 dis[e[i].to]=dis[top]+e[i].w;
48                 if( !using_v[e[i].to] ){
49                     using_v[e[i].to]=1;     //入队
50                     q.push(e[i].to);
51                 }
52             }
53         }
54     }
55     return 1;
56 }
57 
58 int main()
59 {
60     int u,v,w,s;//u--->v的权值为w,s为起点
61     cin>>n>>m>>s;
62     memset(dis,0x3f,sizeof(dis));
63     memset(head,-1,sizeof(head));
64     for(int i=0;i<m;i++){
65         cin>>u>>v>>w;
66         addedge(u,v,w);
67     }
68     spfa(s);
69     for(int i=1;i<=n;i++){
70         if( dis[i]!=inf ){
71             cout<<dis[i]<<endl;
72         }else{
73             cout<<"inf"<<endl;
74         }
75     }
76     return 0;
77 }

 

posted @ 2020-07-27 17:22  swsyya  阅读(112)  评论(0编辑  收藏  举报

回到顶部