zoukankan      html  css  js  c++  java
  • Dijkstra算法模板

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    const int inf=1<<29;
    const int N=1001;
    int n,m,d[N],w[N][N];
    bool vis[N];
    void dij()
    {
        for(int i=1; i<=n; i++)//把从起点到其余每个点的距离设为无穷大,方便此后的松弛操作
            d[i]=inf;
        d[1]=0;//以1为起点
        for(int i=0; i<n; i++)//确保不会遗漏松弛,循环n次(因为每次只取当前与原点距离最小值,每个值都要遍历一遍)
        {
            int now=inf;
            int x;
            for(int j=1; j<=n; j++)//从前到后,把起点到每个点的距离都拿出来比一遍(每一次循环,距离都会有更新)
            {
                if(!vis[j]&&now>d[j])//vis避免前面已经比过了的最小值的点重复比较
                {
                    //一直找出此时离起点最近的点,以此点为基础,向下找其他点到该点的距离,
                    now=d[j];
                    x=j;
                }
            }
           // printf("x=%d
    ",x);
            vis[x]=1;
            for(int j=1; j<=n; j++)//从x点到其他所有点,全部遍历,进行距离的更新(松弛)操作,
            {
                //!vis[j]避免与前面的最小点重复更新
                if(!vis[j]&&d[j]>d[x]+w[x][j])//如果(这一点到x的距离加x到起点的距离)小于之前存的此点到起点的距离
                {
                    d[j]=d[x]+w[x][j];//则更新成新的距离
                    //printf("d[%d]=%d
    ",j,d[j]);
                }
            }
        }
    
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m))//点数,边数
        {
            memset(vis,0,sizeof(vis));
            for(int i=1; i<=n; i++)
            {
                for(int j=1; j<=n; j++)
                {
                    w[i][j]=inf;//点i到点j的距离全部初始化为无穷大
                }
            }
            while(m--)
            {
                int u,v,c;
                scanf("%d%d%d",&u,&v,&c);//起点,终点,权值
                if(c<w[u][v])
                    w[u][v]=w[v][u]=c;//无向图付出权值
            }
            dij();
            for(int i=2; i<=n; i++)//全部输出每个点到起点的最小值
            {
                printf("%d %d
    ",i,d[i]);
            }
        }
        return 0;
    }
    /*
    input
    
    7 12
    1 2 24
    1 3 8
    1 4 15
    2 5 6
    3 5 7
    3 6 3
    4 7 4
    5 7 9
    6 5 2
    6 7 3
    6 4 5
    7 2 3
    
    output
    2 17
    3 8
    4 15
    5 13
    6 11
    7 14*/

     

    局限性:当A到A的距离为0 代码切入到子函数最下方,A到B的距离更新为3,A到C的距离更新为2,再循环找出C点,标记C点已经不能在更新,这是有向图,C不能再向下更新,回去再循环,找出B点,,当B点准备向下更新时,因为之前C点已经被标记,这里会直接跳过C点,不能对其更新,算出的结果是2,但实际上是3-2=1,所以这个算法不能算带有负权值的图

  • 相关阅读:
    Vue $nextTick的一个使用场景
    Vue 使用v-for对Object进行遍历
    JavaScript 回调函数的简单示例
    VSCode 自定义Vue snippets, 快速生成Vue模板
    git将一个分支完全覆盖另外一个分支如:dev分支代码完全覆盖某一个开发分支
    解决bootstrap时间输入框总被浏览器记住的记录遮挡住的问题
    Fiddler 屏蔽JS、抓WebSocket协议、查看接口响应时间、模拟并发请求
    细说MySQL的时间戳(Timestamp)类型
    网站建设之域名注册和域名备案
    日常项目测试用例检查点(来自一线测试人员的吐血总结)
  • 原文地址:https://www.cnblogs.com/tianmin123/p/4774794.html
Copyright © 2011-2022 走看看