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

    lrj紫书十一章

    设m edges,n vertexs

    复杂度 mlog(n)

    算法中以下部分使得每个边都被遍历到,m。而优先队列插入复杂度为log(n).故整体mlog(n)

    注意m可能大于n^2 最后复杂的>n^2.但不常见

     while(!Q.empty()) //第一轮将s能到的点都压入队列,之后每次取d[i]最小的点先出(优先队列)
            {
                HeapNode x=Q.top();Q.pop();
                int u=x.u;                     //u 当前处理点编号
                if(done[u])continue;
                done[u]=true;
                for(int i=0;i<G[u].size();i++)
                {
                    Edge &e=edges[G[u][i]];
                    if(d[e.to]>d[u]+e.dist)
                    {
                        d[e.to]=d[u]+e.dist; //d[u],出发点s到u的距离
                        p[e.to]=G[u][i];     //到达e.to点的边为G[u][i]
                        Q.push(HeapNode(d[e.to],e.to));
                    }
                }
            }
    
    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    
    using namespace std;
    const int maxn = 300 + 5;
    const int INF = 99999999;
    struct Edge
    {
        int from,to,dist;
        Edge(int f=0,int t=0,int d=0):from(f),to(t),dist(d){}
    };
    struct HeapNode//优先队列节点
    {
        int d,u;
        HeapNode(int _d=0,int _u=0):d(_d),u(_u){}
        bool operator<(const HeapNode &rhs)const
        {
            return d>rhs.d;
        }
    };
    struct Dijkstra  //边权为正 负权存在用Bellman-Ford 每两点间最短路floyd
    {
        int n,m;               //点数和边数  O(mlog n)
        vector<Edge> edges;    //边列表
        vector<int> G[maxn];   //每个节点出发的边编号(编号从0开始)
        bool done[maxn];       //是否已永久标号
        int d[maxn];           //s到各个点的距离
        int p[maxn];           //最短路中的上一条边
        void init(int n)
        {
            this->n=n;
            for(int i=0;i<n;i++)G[i].clear();
            edges.clear();
        }
        void AddEdge(int from,int to,int dist)
        {
            edges.push_back(Edge(from,to,dist));
            m=edges.size();
            G[from].push_back(m-1);
        }
    
        void dijkstra(int s)   //s start
        {
            priority_queue<HeapNode> Q;   //优先队列,d[i]越小越先出队
            for(int i=0;i<n;i++)d[i]=INF;
            d[s]=0;
            memset(done,0,sizeof(done));
            Q.push(HeapNode(0,s));
            while(!Q.empty()) //第一轮将s能到的点都压入队列,之后每次取d[i]最小的点先出(优先队列)
            {
                HeapNode x=Q.top();Q.pop();
                int u=x.u;                     //u 当前处理点编号
                if(done[u])continue;
                done[u]=true;
                for(int i=0;i<G[u].size();i++)
                {
                    Edge &e=edges[G[u][i]];
                    if(d[e.to]>d[u]+e.dist)
                    {
                        d[e.to]=d[u]+e.dist; //d[u],出发点s到u的距离
                        p[e.to]=G[u][i];     //到达e.to点的边为G[u][i]
                        Q.push(HeapNode(d[e.to],e.to));
                    }
                }
            }
        }
    };
    
    int main()
    {
        Dijkstra dijk;
        int n,m;                 //n number of vertex m number of edges
        while(scanf("%d%d", &n, &m)==2) {
            dijk.init(n);
            int from,to,dist;
            for(int i = 0; i < m; i++) {
                scanf("%d%d%d",&from,&to,&dist);
                dijk.AddEdge(from,to,dist);
            }
        dijk.dijkstra(0);
        for(int i=0;i<n;i++)
            cout<<"from 0 to "<<i<<"'s minimum distance is :"<<dijk.d[i]<<endl;
        }
        return 0;
    }
    
    
  • 相关阅读:
    ubuntu系统里常用的几个命令
    Vue中常用知识点demo
    Vue基础知识学习(后端)
    ubuntu内lnmp相关操作命令
    linux下安装lnmp集成环境
    js时间戳与日期格式之间相互转换
    yii2中 选择布局的方式,可以设置不使用布局
    yii2中通过migration创建数据表
    php实现支付宝在线支付和扫码支付demo
    linux下添加用户并将文件夹授权给某一个用户
  • 原文地址:https://www.cnblogs.com/lqerio/p/11688501.html
Copyright © 2011-2022 走看看