• 最短路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高级架构师(一)第04节:Git基本原理和安装配置使用
    发光边框
    单位px 转换成 rem
    web app 自适应 弹性布局之rem
    移动端UC /QQ 浏览器的部分私有Meta 属性
    常用<meta>标签
    移动端<head>头部 常用<meta>标签
    移动平台对 META 标签的定义
    减去border边框
    伪类共用样式缩写形式
  • 原文地址:https://www.cnblogs.com/Kohinur/p/8903562.html
Copyright © 2020-2023  润新知