Dijkstra 单源最短路径的实现

最主要的地方就是使用一个数组记录当前到达各点各权值,并不断在访问新点时利用这个已记录的值不断更新

已经访问过的点要立Flag 处理掉

int n, int m, int **Map, bool Path[], int Pre[], int start
分别是:
点数量,边数量,边权,访问状态,前点,起始点

注释很详细,本文章主要是实现,如果不理解建议看b站的视频理解一下

结果

以下是代码,注意看注释

#include <bits/stdc++.h>
using namespace std;
void Display(int result[], int n) 
{ cout<<"ALL MinVal:"<<endl;
  for (int i = 0; i < n; i++)
    cout<<i<<":" <<result[i] << endl;
}
void ShowPath(int n,int Pre[])
{ 
  if(Pre[n]==-1)
  cout<<"Path:"<<endl<<n;
  else 
  {
    ShowPath(Pre[n],Pre);
    cout<<"->"<<n;
  }
}
void Dijkstra(int n, int m, int **Map, bool Path[], int Pre[], int start) //点数量,边数量,边权,访问状态,前点,起始点
{
  int result[n]; //最小权值结果

  fill(result, result + n, INT_MAX); //初始化为最大
  result[start] = 0;
  Pre[start] = -1;
  queue<int> Queues;
  Queues.push(start);
  while (!Queues.empty())
  {
    int Now = Queues.front();

    Queues.pop();

    if (!Path[Now]) //当未访问过
    {
      Path[Now] = true;

      for (int j = 0; j < n; j++)
      {
        if (Map[Now][j] != -1)
        {
          Queues.push(j); //放入待访问中

                                   

          if (result[j] > (Map[Now][j] + result[Now])) //如果小于已记录的值
          {
            result[j] = Map[Now][j] + result[Now];
               Pre[j] = Now;    //j的前节点为 Now
          }
            
        }
      }
    }
  }

  /* 
   //打印图
  for (int i = 0; i < n; i++)
  { cout<<i<<":  ";
    for (int j = 0; j < n; j++)
    { 
      if(Map[i][j]==-1)cout<<"# ";
      else cout<< Map[i][j]<<" ";
    }
    cout<<endl;
  }
 
 */
  int End;
  cout<<"Input Your Distintation  :"<<endl;
  cin>>End;
  ShowPath(End,Pre);
  cout<<endl<<"MinVal:"<<result[End]<<endl;
  Display(result, n); //打印出到各点最小权值
};

void CreateMap()
{
  int n, m; //n个结点,m条边
cout<<"Input Point_Number AND Side_Number :"<<endl;
  cin >> n >> m;

  int Pre[n + 1];   //节点的前节点
  bool Path[n + 1]; //已经走过的路径
  int **Map = new int *[n + 1];
  for (int i = 0; i <= n; i++)
    Map[i] = new int[n];
  memset(Path, false, sizeof(Path)); //初始化Path

  //初始化Map
  for (int i = 0; i <= n; i++)
    for (int j = 0; j <= n; j++)
      Map[i][j] = -1;

  //输入边
  int x, y, val;
  for (int i = 0; i < m; i++)
  {
    cin >> x >> y >> val;
    Map[x][y] = val;
    Map[y][x] = Map[x][y];
  }

  int start = 0; //起始点
  cout <<"Input Your Origin:"<<endl;
    cin >> start;
  //Dijkstra
  Dijkstra(n, m, Map, Path, Pre, start);
}
int main()
{
  CreateMap();

  system("pause");
}
/*
9 14
0 1 4
0 7 8
1 7 11
1 2 8
2 8 2
7 8 7
7  6 1
6 5 2
8 6 6
2 5 4
3 5 14
3 4 9
4 5 10
2 3 7
0
4
*/
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王也枉不了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值