zoukankan      html  css  js  c++  java
  • 最短路dijkstra,SPFA

    Dijkstra算法

    Dijkstra算法采用的是一种贪心的策略。

    dijkstra不能有负权边

    声明一个数组d来保存源点到各个顶点的最短距离和一个保存已经找到了最短路径的顶点的集合:T。

    初始时,原点 s 的路径权重被赋为 0 (d[s] = 0)。若对于顶点 s 存在能直接到达的边(s,m),则把d[m]设为s到m的距离,同时把所有其他(s不能直接到达的)顶点的路径长度设为无穷大。初始时,集合T只有顶点s。 

    然后,从dis数组选择最小值,则该值就是源点s到该值对应的顶点的最短路径,并且把该点加入到T中,OK,此时完成一个顶点, 
    然后,我们需要看看新加入的顶点是否可以到达其他顶点并且看看通过该顶点到达其他点的路径长度是否比源点直接到达短,如果是,那么就替换这些顶点在dis中的值。 
    然后,又从dis中找出最小值,重复上述动作,直到T中包含了图的所有顶点。

    dijkstra模板:

    #include<stdio.h>
    #include<string.h>
    #define INFINITY 1000
    int d[100];
    int final[100];
    int g[100][100];
    int n;
    void dijkstra(int s)
    {
        int min, w, v, i, j;
        memset(final, 0, sizeof(final));
        for(v = 1; v <= n; v++)
            d[v] = g[s][v];
        final[s] = 1;
        d[s] = 0;
        for(i = 2; i <= n; i++)//这个点对应的一行的每一个点的最短都找出来
        {
            min = INFINITY;
            v = -1;
            for(w = 1; w <= n; w++) //在所有末标识的点中,选D值最小的点
            {
                if(!final[w] && d[w] < min)
                {
                    v = w;
                    min = d[w];
                }
            }
    
            if(v != -1)//如果v=-1表示现在在找的这个点没有与其他任何点有路径
            {
                final[v] = 1;
    
                for(w = 1; w <= n; w++)//找到最段路径后对应的与之相连的新点
                    if((!final[w]) && (g[v][w] < INFINITY))
                    {
                        if(d[w] > min + g[v][w])
                            d[w] = min + g[v][w];
                    }
            }
        }
    }
    int main()
    {
        int i, j;
        scanf("%d", &n);
        for(i = 1; i <= n; i++)
            for(j = 1; j <= n; j++)
                scanf("%d", &g[i][j]);
        dijkstra(1);
        for(i = 1; i <= n; i++)
            printf("%d ", d[i]);
        return 0;
    }

     spfa算法

    spfa可以有负权边

    主要应用queue队列

    有关spfa算法,这个博客写的很详细:最快最好用的——spfa算法

    模板(这个是hdoj通畅工程续的ac代码):

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define inf 99999999
     4 #define maxn 210
     5 int maps[maxn][maxn];
     6 int visited[maxn], dis[maxn];
     7 int n, m;
     8 queue<int> q;
     9 int spfa(int s, int t)
    10 {
    11     for(int i = 0; i < n; i++)
    12     {
    13         dis[i] = inf;
    14         visited[i] = 0;
    15     }
    16     while(!q.empty())
    17         q.pop();
    18     dis[s] = 0;
    19     visited[s] = 1;
    20     q.push(s);//起点入队
    21 
    22     while(!q.empty())
    23     {
    24         int temp = q.front();
    25         q.pop();
    26         visited[temp] = 0;
    27         for(int i = 0; i < n; i++)
    28         {
    29             if(dis[i] > dis[temp] + maps[temp][i])
    30             {
    31                 dis[i] = dis[temp] + maps[temp][i];
    32                 if(visited[i] == 0)
    33                 {
    34                     visited[i] = 1;
    35                     q.push(i);//当前最短距离的点入队
    36                 }
    37             }
    38 
    39         }
    40     }
    41     if(dis[t] == inf)
    42         return -1;
    43     else
    44         return dis[t];
    45 }
    46 int main()
    47 {
    48     int a, b, x, s, t, ans;
    49     while(scanf("%d %d", &n, &m) != EOF)
    50     {
    51         for(int i = 0; i < n; i++)
    52             for(int j = 0; j < n; j++)
    53                 maps[i][j] = (i == j ? 0 : inf);
    54         while(m--)
    55         {
    56             scanf("%d %d %d", &a, &b, &x);
    57             if(x < maps[a][b])
    58                 maps[a][b] = maps[b][a] = x;
    59         }
    60         scanf("%d %d", &s, &t);
    61         ans = spfa(s, t);
    62         printf("%d
    ", ans);
    63     }
    64     return 0;
    65 }

    参考博客:最短路径问题---Dijkstra算法详解  最快最好用的——spfa算法

  • 相关阅读:
    Java-单机版的书店管理系统(练习设计模块和思想_系列 二 )
    HDOJ 1279 验证角谷猜想
    HDOJ 1266 Reverse Number(数字反向输出题)
    lucas定理
    CRT && exCRT模板
    exgcd模板
    洛谷P4774 屠龙勇士
    洛谷P1477 假面舞会
    洛谷P2704 炮兵阵地
    CF1080
  • 原文地址:https://www.cnblogs.com/Kohinur/p/8903562.html
Copyright © 2011-2022 走看看