zoukankan      html  css  js  c++  java
  • [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),必须慎用

     

  • 相关阅读:
    再谈后兵 FileInfo 与 DirectoryInfo类 清晰的winform界面(技术改变世界cnblog)
    在.NET Core中使用Channel(二)
    C#中的依赖注入和IoC容器
    改进你的c#代码的5个技巧(一)
    将WCF迁移到gRPC
    在.NET Core中使用Channel(三)
    在.NET Core中使用Channel(一)
    .NET 5 源代码生成器——MediatR——CQRS
    在大型软件项目中如何处理错误和异常
    在 ASP.NET Core和Worker Service中使用Quartz.Net
  • 原文地址:https://www.cnblogs.com/nlyzl/p/11770101.html
Copyright © 2011-2022 走看看