• 最短路径


    Dijkstra算法实现最短路径

    问题描述

    若用有向网表示某地区的公路交通网,其中顶点表示该地区的一些主要场所,弧表示已有的公交线路,弧上的权表示票价。试设计一个交通咨询系统,指导乘客以最少花费从该地区中的某一场所到达另一场所。
    基本要求
    (1) 从文件中读入有向网中顶点的数量和顶点间的票价的矩阵。
    (2) 以用户指定的起点和终点,输出从起点到终点的花费。
    测试数据
    输入
    (文件)
    5
    -1 10 3 20 -1
    -1 -1 -1 5 -1
    -1 2 -1 -1 15
    -1 -1 -1 -1 11
    -1 -1 -1 -1 -1
    (用户)
    起点0
    终点4

    输出
    18
    实现提示
    (1) 设图的顶点大于1个,不超过30个,每个顶点用一个编号表示(如果一个图有n个顶点,则它们的编号分别为0, 1, 2, 3, …, n-1)。
    (2) 此题为求有向网中顶点间最短路径问题,可建立以票价为权的邻接矩阵,用Dijkstra算法求最短路径长度。
    (3) Dijkstra算法中有一个辅助向量D,表示当前所找到的从源点到其它点的最短路径长度。因为每次都要在D中找最小值,为提高性能,用最小值堆的优先队列存储D值。
    (4) 考虑没有路径时的输出。
    选作内容
    (1) 以用户指定的起点,输出到其它各点的花费。
    (2) 以用户指定的起点和终点,输出从起点到终点的花费以及路径(经过的中间顶点)。

     必做

      1 #include<iostream>
      2 #include<fstream>
      3 #include<stdio.h>
      4 #include<stdlib.h>
      5 #include<string.h>
      6 #include<string>
      7 #define maxSize 100
      8 #define maxint 1000
      9 typedef enum{ FALSE, TRUE }Boolean;
     10 Boolean visited[maxSize];
     11 using namespace std;
     12 int read(int graph[][maxSize])
     13 {
     14     FILE *in;
     15     in=fopen("path","r");
     16     int n,i,j,num;
     17     fscanf(in,"%d",&n);
     18 
     19     for(i=0;i<n;i++)
     20     {
     21         for(j=0;j<n;j++)
     22         {
     23             fscanf(in,"%d",&num);
     24             if(num==-1)
     25                 num=maxint;
     26             graph[i][j]=num;
     27         }
     28     }
     29 
     30 
     31     fclose(in);
     32     return n;
     33 }
     34 int first(int v,int n,int graph[maxSize][maxSize])
     35 {
     36     int j;
     37     int ret;
     38     for(j=1;j<n;j++)
     39     {
     40         if(graph[v][j]!=-1)
     41             {return j;break;}
     42     }
     43     if(j==n)
     44         return n;
     45 }
     46 int next(int v,int w,int n,int graph[maxSize][maxSize])
     47 {
     48     int j;
     49     for(j=w+1;j<n;j++)
     50     {
     51         if(graph[v][j]!=-1)
     52             {return j;break;}
     53     }
     54     if(j==n)
     55     return n;
     56 }
     57 int minn(int *dist,int n,int v)
     58 {
     59     int j,mi;
     60 
     61     for(j=0;j<n;j++)
     62     {
     63         if(dist[j]!=maxint&&visited[j]==FALSE)
     64             {mi=j;break;}
     65     }
     66     if(j==n)
     67     {cout<<"不存在路径"<<endl;return -1;}
     68     for(j++;j<n;j++)
     69     {
     70         if(dist[j]<dist[mi]&&dist[j]!=maxint&&visited[j]==FALSE)
     71             mi=j;
     72     }
     73     return mi;
     74 }
     75 bool Dijkstra(int n, int v, int *dist, int graph[maxSize][maxSize])
     76 {
     77     //找到与V相邻的最短路径的结点
     78     int i,j,mi,w;
     79     for(j=0;j<n;j++)
     80         visited[j]=FALSE;//初始化为都没有被访问
     81     for(j=0;j<n;j++)
     82         {dist[j]=graph[v][j];}
     83     mi=minn(dist,n,v);
     84 
     85     visited[mi]=TRUE;
     86     cout<<"mi___"<<mi<<endl;
     87     i=0;
     88     while(i<n-1)
     89     {
     90 
     91 
     92         for(j=0;j<n;j++)
     93         {
     94             if(dist[j]>dist[mi]+graph[mi][j])
     95             {dist[j]=dist[mi]+graph[mi][j];}
     96         }
     97         visited[mi]=TRUE;
     98         mi=minn(dist,n,mi);
     99         cout<<"mi  "<<mi<<endl;
    100         i++;
    101     }
    102 }
    103 int main()
    104 {
    105     int graph[maxSize][maxSize],n,i,j;
    106     int from,to;
    107     int dis[maxSize],pre[maxSize];
    108     n=read(graph);
    109 
    110     for(i=0;i<n;i++)
    111     {
    112         for(j=0;j<n;j++)
    113         {
    114             cout<<graph[i][j]<<" ";
    115         }
    116         cout<<endl;
    117     }
    118     cout<<"起点 :";
    119     cin>>from;
    120     cout<<"终点 :";
    121     cin>>to;
    122 
    123     Dijkstra(n,from,dis,graph);
    124     for(i=0;i<n;i++)
    125         cout<<dis[i]<<" "<<endl;
    126     cout<< ""<<from<<""<<to<<"的最短距离:  "<<dis[to]<<endl;
    127     return 0;
    128 }
    View Code

    选做1

      1 #include<iostream>
      2 #include<fstream>
      3 #include<stdio.h>
      4 #include<stdlib.h>
      5 #include<string.h>
      6 #include<string>
      7 #define maxSize 100
      8 #define maxint 1000
      9 typedef enum{ FALSE, TRUE }Boolean;
     10 Boolean visited[maxSize];
     11 using namespace std;
     12 int read(int graph[][maxSize])
     13 {
     14     FILE *in;
     15     in=fopen("path","r");
     16     int n,i,j,num;
     17     fscanf(in,"%d",&n);
     18 
     19     for(i=0;i<n;i++)
     20     {
     21         for(j=0;j<n;j++)
     22         {
     23             fscanf(in,"%d",&num);
     24             if(num==-1)
     25                 num=maxint;
     26             graph[i][j]=num;
     27         }
     28     }
     29 
     30 
     31     fclose(in);
     32     return n;
     33 }
     34 int first(int v,int n,int graph[maxSize][maxSize])
     35 {
     36     int j;
     37     int ret;
     38     for(j=1;j<n;j++)
     39     {
     40         if(graph[v][j]!=-1)
     41             {return j;break;}
     42     }
     43     if(j==n)
     44         return n;
     45 }
     46 int next(int v,int w,int n,int graph[maxSize][maxSize])
     47 {
     48     int j;
     49     for(j=w+1;j<n;j++)
     50     {
     51         if(graph[v][j]!=-1)
     52             {return j;break;}
     53     }
     54     if(j==n)
     55     return n;
     56 }
     57 int minn(int *dist,int n,int v)
     58 {
     59     int j,mi;
     60 
     61     for(j=0;j<n;j++)
     62     {
     63         if(dist[j]!=maxint&&visited[j]==FALSE)
     64             {mi=j;break;}
     65     }
     66     if(j==n)
     67     {
     68         //cout<<"不存在路径"<<endl;
     69         return -1;
     70     }
     71     for(j++;j<n;j++)
     72     {
     73         if(dist[j]<dist[mi]&&dist[j]!=maxint&&visited[j]==FALSE)
     74             mi=j;
     75     }
     76     return mi;
     77 }
     78 bool Dijkstra(int n, int v, int *dist, int graph[maxSize][maxSize])
     79 {
     80     //找到与V相邻的最短路径的结点
     81     int i,j,mi,w;
     82     for(j=0;j<n;j++)
     83         visited[j]=FALSE;//初始化为都没有被访问
     84     for(j=0;j<n;j++)
     85         {dist[j]=graph[v][j];}
     86     mi=minn(dist,n,v);
     87 
     88     visited[mi]=TRUE;
     89     //cout<<"mi___"<<mi<<endl;
     90     i=0;
     91     while(i<n-1)
     92     {
     93 
     94 
     95         for(j=0;j<n;j++)
     96         {
     97             if(dist[j]>dist[mi]+graph[mi][j])
     98             {dist[j]=dist[mi]+graph[mi][j];}
     99         }
    100         visited[mi]=TRUE;
    101         mi=minn(dist,n,mi);
    102       //  cout<<"mi  "<<mi<<endl;
    103         i++;
    104     }
    105 }
    106 int main()
    107 {
    108     int graph[maxSize][maxSize],n,i,j;
    109     int from,to;
    110     int dis[maxSize],pre[maxSize];
    111     n=read(graph);
    112 
    113     for(i=0;i<n;i++)
    114     {
    115         for(j=0;j<n;j++)
    116         {
    117             cout<<graph[i][j]<<" ";
    118         }
    119         cout<<endl;
    120     }
    121     cout<<"起点 :";
    122     cin>>from;
    123     cout<<"终点 :";
    124     cin>>to;
    125 
    126     Dijkstra(n,from,dis,graph);
    127     for(i=0;i<n;i++)
    128         cout<<"起点到点"<<i<<"的最短距离"<<dis[i]<<" "<<endl;
    129     //cout<< "从"<<from+1<<"到"<<to+1<<"的最短距离:  "<<dis[to]<<endl;
    130     return 0;
    131 }
    View Code

    选做2

      1 /***************************************
      2 * About:    有向图的Dijkstra算法实现
      3 * Author:   Tanky Woo
      4 * Blog:     www.WuTianQi.com
      5 ***************************************/
      6 
      7 #include <iostream>
      8 #include<stdio.h>
      9 using namespace std;
     10 
     11 const int maxnum = 100;
     12 const int maxint = 1000;
     13 
     14 int read(int graph[][maxnum])
     15 {
     16     FILE *in;
     17     in=fopen("path","r");
     18     int n,i,j,num;
     19     fscanf(in,"%d",&n);
     20 
     21     for(i=1;i<=n;i++)
     22     {
     23         for(j=1;j<=n;j++)
     24         {
     25             fscanf(in,"%d",&num);
     26             if(num==-1)
     27                 num=maxint;
     28             graph[i][j]=num;
     29         }
     30     }
     31 
     32 
     33     fclose(in);
     34     return n;
     35 }
     36 
     37 void Dijkstra(int n, int v, int *dist, int *prev, int c[maxnum][maxnum])
     38 {
     39     bool s[maxnum];    // 判断是否已存入该点到S集合中
     40     for(int i=1; i<=n; ++i)
     41     {
     42         dist[i] = c[v][i];
     43         s[i] = 0;     // 初始都未用过该点
     44         if(dist[i] == maxint)
     45             prev[i] = 0;
     46         else
     47             prev[i] = v;
     48     }
     49     dist[v] = 0;
     50     s[v] = 1;
     51 
     52     // 依次将未放入S集合的结点中,取dist[]最小值的结点,放入结合S中
     53     // 一旦S包含了所有V中顶点,dist就记录了从源点到所有其他顶点之间的最短路径长度
     54     for(int i=2; i<=n; ++i)
     55     {
     56         int tmp = maxint;
     57         int u = v;
     58         // 找出当前未使用的点j的dist[j]最小值
     59         for(int j=1; j<=n; ++j)
     60             if((!s[j]) && dist[j]<tmp)
     61             {
     62                 u = j;              // u保存当前邻接点中距离最小的点的号码
     63                 tmp = dist[j];
     64             }
     65         s[u] = 1;    // 表示u点已存入S集合中
     66 
     67         // 更新dist
     68         for(int j=1; j<=n; ++j)
     69             if((!s[j]) && c[u][j]<maxint)
     70             {
     71                 int newdist = dist[u] + c[u][j];
     72                 if(newdist < dist[j])
     73                 {
     74                     dist[j] = newdist;
     75                     prev[j] = u;
     76                 }
     77             }
     78     }
     79 }
     80 
     81 void searchPath(int *prev,int v, int u)
     82 {
     83     int que[maxnum];
     84     int tot = 1;
     85     que[tot] = u;
     86     tot++;
     87     int tmp = prev[u];
     88     while(tmp != v)
     89     {
     90         que[tot] = tmp;
     91         tot++;
     92         tmp = prev[tmp];
     93     }
     94     que[tot] = v;
     95     for(int i=tot; i>=1; --i)
     96         if(i != 1)
     97             cout << que[i] << " -> ";
     98         else
     99             cout << que[i] << endl;
    100 }
    101 
    102 int main()
    103 {
    104 
    105     //freopen("input.txt", "r", stdin);
    106     // 各数组都从下标1开始
    107     int dist[maxnum];     // 表示当前点到源点的最短路径长度
    108     int prev[maxnum];     // 记录当前点的前一个结点
    109     int graph[maxnum][maxnum];   // 记录图的两点间路径长度
    110     int n;
    111     n=read(graph);
    112 
    113 
    114     for(int i=1; i<=n; ++i)
    115         dist[i] = maxint;
    116     for(int i=1; i<=n; ++i)
    117     {
    118         for(int j=1; j<=n; ++j)
    119             cout<<graph[i][j]<<" ";
    120         cout<<endl;
    121     }
    122     int from,to;
    123     cout<<"起点:";
    124     cin>>from;
    125     cout<<"终点:";
    126     cin>>to;
    127     Dijkstra(n, from+1, dist, prev, graph);
    128 
    129     // 最短路径长度
    130     cout << "起点到终点的最短路径长度: " << dist[to+1] << endl;
    131 
    132     // 路径
    133     cout << "起点到终点的路径为: ";
    134     searchPath(prev, from+1, to+1);
    135 }
    View Code

    文件名是path    二进制文件

  • 相关阅读:
    windows下vagrant使用及工作环境配置
    使用docker搭建lnmp环境
    Docker常用命令
    [docker] 管理docker容器中的数据
    python初始化父类错误
    Linux--
    用少于2MB内存存下5百万个介于0到1千万之间的整数
    k路归并:数组、链表
    剑指offer新思路
    阿里电话面试
  • 原文地址:https://www.cnblogs.com/zhenzhenhuang/p/5506031.html
Copyright © 2020-2023  润新知