Dijkstra-point-to-point shortest path and distance

基本思想 source -> target

1.找出源节点到所有节点的距离dist[i],取最小值,对应的就是源节点到该节点node的最短路径;

2.if(node==target)return dist[target];

3.根据1步找到的最短路径,(dist[node] + edge[node][j] < dist[j])更新源节点到各个节点的距离;否则不更新;

4.重复以上步骤。




#include <iostream>

#include <cstdio>
#include <vector>
#include <cstdlib>
#include <time.h>
#include <stack>


using namespace std;




const int nodes = 10001;///图中节点个数
int edges[nodes][nodes];///图的邻接矩阵
bool nodeState[nodes];///判断源节点到i节点是否已经找到最短路径
int dist[nodes];///表示源节点到节点i的最短距离
int INIFITE = 2147483647;
int MIN_Value = 0x7fffffff;
int path[nodes];///路径存储,path[i]表示i的前驱
std::stack<int> shortest_path; ///利用paths数组,进栈,然后按照路径顺序打印






///读入图文件,初始化邻接矩阵
void init_Edges()
{
    for(int i=1;i<nodes;i++)
        for(int j=1;j<nodes;j++)
            edges[i][j] = INIFITE;
    int node1,node2,weight;
    char filename[20] ;
    cout<<"please input graph file name :";
    cin>>filename;
    FILE *read_resultFile = fopen(filename,"r");


    if(read_resultFile == NULL)
    {
        cout<<"open endresult.txt fail"<<endl;
        return ;
    }
    cout<<"正在读文件,初始化图邻接矩阵"<<endl;
    while(!feof(read_resultFile))
    {
        fscanf(read_resultFile,"%d  %d  %d",&node1,&node2,&weight);
        edges[node1][node2] = weight;
        edges[node2][node1] = weight;
    }


    fclose(read_resultFile);


}
///标记到节点i最短路径是否找到
void init_NodeState()
{
    for(int i=1;i<nodes;i++)
        nodeState[i] = false;///=false说明源节点到i的最短路径还没找到
}


///初始化dist数组;dist[i]表示源节点到节点i 最小距离
void init_Dist(int source)
{
    for(int i=1;i<nodes;i++)
        dist[i] = edges[source][i];
}


///初始化路径数组,将源节点邻居的前驱置为source
void init_Path(int source)
{


    for(int i=1;i<nodes;i++)
    {
        if(dist[i] < INIFITE)
            path[i] = source;
        else
            path[i] = -1;
    }
}


/*void visit()
{
    for(int i =1; i<nodes;i++)
        isGray[i] = false;
}*/


///利用Dijkstra算法,求解最短路径


int ShortestPath_Dijkstra(int source,int target)
{
    if(source == target)
        return 0;
    for(int i=1;i<nodes;i++)
        dist[i] = INIFITE;
    init_NodeState();
    init_Dist(source);
    init_Path(source);


//    for(int i=1;i<nodes;i++)
//    {
//        nodeState[i] = false;
//        dist[i] = edges[source][i];
//
//        if(dist[i]<INIFITE)
//            path[i] = source;
//        else
//            path[i] = -1;
//    }


    nodeState[source] = true;
    dist[source] = 0;








//for(int i=1;i<nodes;i++)
//            cout<<dist[i]<<" ";
//        cout<<endl;
    int tempNode ;
    int minValue;
    for(int i=1;i<nodes;i++)
    {


        minValue = INIFITE;
        for(int j=1;j<nodes;j++) ///循环找出当前路径的最小值
        {
            if(!nodeState[j] && dist[j] < minValue)
            {


                minValue = dist[j];


                tempNode = j;
            }




        }
        ///cout<<"tempNode ="<<tempNode<<endl;
        nodeState[tempNode] = true;
        /**********for(int i=1;i<nodes;i++)
            cout<<dist[i]<<" ";
        cout<<endl;
****************/
        if(tempNode == target)return dist[target];///找到目的节点,返回最小值




        for(int j=1;j<nodes;j++)
        {
            if(nodeState[j]==false && ((dist[tempNode] + edges[tempNode][j]) < dist[j]) && edges[tempNode][j] <INIFITE)
            {
                dist[j] = dist[tempNode] + edges[tempNode][j];
                path[j] = tempNode;
            }
        }
    }
    return minValue;


}


int main()
{
    int source,target;
    srand((unsigned)time(NULL));
    source = rand() % (nodes - 1) + 1;
    target = rand() % (nodes - 1) + 1;
    init_Edges();
//    cout<<source<<"  "<<target<<endl;
   /* for(int i=1;i<nodes;i++)
    {
        for(int j=1;j<nodes;j++)
            cout<<edges[i][j]<<" " ;
        cout<<endl;
    }*/


    int Distance = ShortestPath_Dijkstra(source,target);


    cout<<source<<" -> "<<target<<" shortest distance is : "<<Distance<<endl;
    cout<<"shortest path is:";




    int temp = target;
    shortest_path.push(target);
    while(temp != source)
    {
        shortest_path.push(path[temp]);
        temp = path[temp];
    }
    //cout<<source<<"->";
    while(!shortest_path.empty())
    {
        cout<<shortest_path.top()<<"->";
        shortest_path.pop();
    }


    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值