zoukankan      html  css  js  c++  java
  • 单源最短路 Dijkstra

    /*
        Dijkstra 算法求单源最短路径
        将所有结点分为两个集合 S D ,S为未访问的结点集合,D为已访问的集合
        每次从集合D中找到一条到达集合S中结点的最短路径,将该点加入到D集合,并更新加入该点后的最短路径
    */
    #include<iostream>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int MAX=1E9;
    const int Size=720;
    class Dist{ //存放找到的当前最短路径
    public:
        int index; //结点下标
        int length; //路径长度
        int pre; //当前结点前驱下标
        friend const bool operator < (const Dist &a,const Dist &b)
        {
            return a.length>b.length;//小的优先级高,用于优先队列
        }
    };
    class Graph{
    public:
        int numv; //结点数
        int *mark; //标记已访问结点,未访问为0
        int * *ma; //邻接矩阵
        Graph(int n)
        {
            numv=n;
            ma=(int * *)new int [n];
            for(int i=0;i<n;i++)ma[i]=new int[n];
            mark=new int [n];
        }
    };
    void Dijkstra(Graph &G,int s,Dist* &D) //s为源点
    {
        using std::priority_queue;
        D=new Dist[G.numv];
        for(int i=0;i<G.numv;i++) //Dist初始化
        {
            G.mark[i]=0;
            D[i].index=i;
            D[i].length=MAX; //Dist存放长度为极大值,若算法结束后仍为极大值认为未找到可达路径
            D[i].pre=s;
        }
        D[s].length=0;
        priority_queue<Dist> H; //优先队列,存放最短路径
        H.push(D[s]);
        for(int i=0;i<G.numv;i++)
        {
            bool f=false;
            Dist d;
            while(!H.empty())
            {
                d=H.top();
                H.pop();
                if(G.mark[d.index]==0) //寻找未访问结点
                {
                    f=true;
                    break;
                }
            }
            if(!f)break; //未找到可访问结点退出
            int v=d.index; //v找到的当前结点
            G.mark[v]=1; //标记v为已访问
            for(int i=0;i<G.numv;i++)
            {
                if(G.ma[v][i]>0) //访问v的边,i为目标点
                {
                    if(D[i].length>(D[v].length+G.ma[v][i])) //若经过v的某条边,使得s到i的距离比Dist中存放的最短路更短
                    {
                        D[i].length=D[v].length+G.ma[v][i]; //更新Dist[i](s到i的最短路)
                        D[i].pre=v; //改变到i的最短路前驱为v
                        H.push(D[i]); //将新的最短路放入优先队列
                    }
                }
            }
        }
    }
    int main()
    {
        int n;cout <<"d"<<endl;
        int a,b,c,e;
        Dist *d;
        Graph g(100);
        while(cin>>n)
        {
            g.numv=n+1;
            for(int i=0;i<=n;i++)g.mark[i]=0;
            for(int i=0;i<=n;i++)
                for(int j=0;j<=n;j++)
                    g.ma[i][j]=0;
            while(cin>>a>>b)
            {
                if(a==-1&&b==-1)break;
                cin >> c;
                g.ma[a][b]=c;
            }
            cin>>e;
            Dijkstra(g,e,d);
            for(int i=1;i<n+1;i++)
                cout << d[i].index << " " <<d[i].length <<" "<<d[i].pre<<endl;
    
        }
        return 0;
    }
    /*
    3
    1 2 8
    1 3 3
    3 2 3
    -1 -1
    1
    5
    1 4 30
    1 2 10
    1 5 100
    2 3 50
    3 5 10
    4 5 60
    4 2 10
    4 3 20
    -1 -1
    1
    6
    1 3 15
    2 1 10
    2 4 2
    2 6 30
    4 2 20
    4 5 15
    5 2 4
    6 3 4
    6 5 10
    6 1 10
    -1 -1
    2
    */
    
  • 相关阅读:
    2016012056+小学四则运算练习软件项目报告
    《构建之法》1,2,16章读后感
    我与软件
    散列函数的应用及其安全性
    EGener2四则运算出题器
    用jar包运行带GUI的java游戏
    关于《构建之法》第四章和第十七章的问题
    2016012070小学四则运算练习软件项目报告
    有关软件工程的一些问题
    300道随机四则运算小程序(java编写)
  • 原文地址:https://www.cnblogs.com/LowBee/p/9049958.html
Copyright © 2011-2022 走看看