[Usaco2009 Oct]Heat Wave 热浪 最短路之spfa

本人水平有限,题解不到为处,请多多谅解

本蒟蒻谢谢大家观看

关于spfa,它死了。

但是spfa还是有优点的:

SPFA算法是西南交通大学段凡丁于1994年发表的。

SPFA 也是竞赛中最常见的算法之一,不仅仅用来解决带负权的单源最短路

而且是求解差分约束问题的专用算法,也常用它和最大流合作解决最小费问题

题目传送门

题目大意:

spfa模板,用循环队列优化

直接套模板即可。

code:

 1 #include<bits/stdc++.h>
 2 #define inf 0x3f3f3f3f
 3 #pragma GCC optimize(3)
 4 const int N=1e5+10;
 5 using namespace std;
 6 int T,C,s,e;
 7 int ver[N*2],nxt[N*2],head[N],edge[N*2];
 8 int dis[N];
 9 bool vis[N];
10 int tot;
11 queue<int>q;//循环队列,可重复进出 
12 inline int read(){
13     int x=0,f=1;char ch=getchar();
14     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
15     while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
16     return x*f;
17 }
18 inline void write(int x)
19 {
20     if(x<0)x=-x,putchar('-');
21     if(x>9)write(x/10);
22     putchar(x%10+'0');
23 }
24 void add(int x,int y,int z){
25     ++tot;
26     ver[tot]=y;
27     edge[tot]=z;
28     nxt[tot]=head[x];
29     head[x]=tot;
30 }
31 int spfa(int b){
32     for(int i=1;i<=T;i++){
33         dis[i]=inf;//初始距离最大 
34         vis[i]=0;//所有点都没有进队列 
35     }
36     dis[b]=0;//是以b为根,所以初始b的距离为0 
37     vis[b]=1;//初始b进队列 
38     q.push(b);
39     while(q.size()){//只有当队列不为空时才能继续访问 
40         int x=q.front();//取出队首 
41         q.pop();
42         vis[x]=0;//x出队列,此时x已不在队中 
43         for(int i=head[x];i;i=nxt[i]){
44             int y=ver[i],z=edge[i];
45             if(dis[y]>dis[x]+z){
46                 dis[y]=dis[x]+z;//更新以b为根到y的距离的最小值 
47                 if(!vis[y]){//若y还没有进队列 
48                     q.push(y);//让y进队列 
49                     vis[y]=true;//此时y已入队 
50                 }
51             }
52         }
53     }
54 }
55 int main()
56 {
57     T=read(),C=read();
58     s=read(),e=read();
59     for(int i=1,x,y,z;i<=C;i++){
60         x=read(),y=read(),z=read();
61         add(x,y,z);
62         add(y,x,z);
63     }
64     spfa(s);
65     printf("%d
",dis[e]);
66     return 0;
67 }
68 /*
69 7 11 5 4
70 2 4 2
71 1 4 3
72 7 2 2
73 3 4 3
74 5 7 5
75 7 3 3
76 6 1 1
77 6 3 4
78 2 4 3
79 5 6 3
80 7 2 1
81 */

注意:由于一个节点可能入队,出队多次,在一些特殊图上,可能出题人会卡spfa,将原本的O(km)退化成O(nm),必须慎用

 

原文地址:https://www.cnblogs.com/nlyzl/p/11770101.html