• hdu2544SPFA板题


    SPFA顾名思义就是更快的最短路算法,是Bellman ford算法的优化,SPFA的平均复杂度大约是O(K*|E|),在一般情况下K大约是小于等于2的数,但是总有人对你心怀不轨,构造一组SPFA最坏情形下的数据来卡你,这时候SPFA的复杂度可以达到接近二次指数。SPFA的优点在于可以判断负环,这要从算法的执行方式说起。SPFA的执行过程就是不断地迭代,不断取出队首元素进行松弛直到队列为空。这个做法是是基于三角不等式的,两边之和如果小于第三边则更新第三边的最短路径长度。一个点取出后对其他店进行松弛之后,它可能还会被其他点松弛,再次入队,所以一个点会多次进入队列,如果一个点进入队列的次数大于点的数量,说明存在负环,每次该点都能被松弛并放入队列。所以SPFA有着比dijkstra独特的优势。

    代码如下:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef unsigned int ui;
     4 typedef long long ll;
     5 typedef unsigned long long ull;
     6 #define pf printf
     7 #define mem(a,b) memset(a,b,sizeof(a))
     8 #define prime1 1e9+7
     9 #define prime2 1e9+9
    10 #define pi 3.14159265
    11 #define lson l,mid,rt<<1
    12 #define rson mid+1,r,rt<<1|1
    13 #define scand(x) scanf("%llf",&x) 
    14 #define f(i,a,b) for(int i=a;i<=b;i++)
    15 #define scan(a) scanf("%d",&a)
    16 #define mp(a,b) make_pair((a),(b))
    17 #define P pair<int,int>
    18 #define dbg(args) cout<<#args<<":"<<args<<endl;
    19 #define inf 0x3f3f3f3f
    20 const int maxn=10010;
    21 int n,m,t,e;
    22 int head[maxn],nxt[maxn],d[maxn],in[maxn];
    23 struct node{
    24     int v,w;
    25 }p[maxn];
    26 void init()
    27 {
    28     e=0;
    29     mem(head,-1);
    30     mem(nxt,-1);
    31 }
    32 void addedge(int u,int v,int w)
    33 {
    34     p[e].v=v;
    35     p[e].w=w;
    36     nxt[e]=head[u];
    37     head[u]=e++;
    38 }
    39 void spfa(int src)
    40 {
    41     f(i,1,n)d[i]=inf;
    42     d[src]=0;
    43     mem(in,false);
    44     queue<int>q;
    45     in[src]=1;
    46     q.push(src);
    47     while(!q.empty())
    48     {
    49         int now=q.front();
    50         q.pop();
    51         in[now]=0;
    52         for(int i=head[now];~i;i=nxt[i])
    53         {
    54             if(d[p[i].v]>d[now]+p[i].w)//松弛 
    55             {
    56                 d[p[i].v]=d[now]+p[i].w;
    57                 if(!in[p[i].v])
    58                 {
    59                     q.push(p[i].v);
    60                     in[p[i].v]=1;//不在队列中就入队 
    61                 } 
    62             }
    63         }
    64     }
    65  } 
    66 int main()
    67 {
    68     //freopen("input.txt","r",stdin);
    69     //freopen("output.txt","w",stdout);
    70     std::ios::sync_with_stdio(false);
    71      while(scanf("%d%d",&n,&m)==2&&!(n==0&&m==0))
    72      {
    73          int u,v,w;
    74          init();
    75          f(i,1,m)
    76         {
    77              scanf("%d%d%d",&u,&v,&w);
    78          addedge(u,v,w);
    79          addedge(v,u,w);
    80         }
    81         spfa(1);
    82         pf("%d
    ",d[n]);
    83      }
    84  } 
  • 相关阅读:
    Flutter Android ERROR: ensureInitializationComplete must be called after startInitialization
    MySQL 创建用户表和好友表
    Android 广播的使用 文档使用的是 kotlin版本
    Flutter 分段器的使用
    Flutter 计算两个日期之间相差多少天,生成区间随机数
    Flutter 多环境
    Android ListView 的使用 Kotlin
    Android 自定义控件----基础
    Flutter 学习(3)------------通过List或者map循环数据渲染页面。。
    vs2015 编译报错:The project references NuGet package(s) that are missing on this computer...
  • 原文地址:https://www.cnblogs.com/randy-lo/p/12552127.html
Copyright © 2020-2023  润新知