• 7-35 城市间紧急救援 (25分)-dijkstra最短路径


      1 #include <iostream>
      2 #define infinity 65535
      3 using namespace std;
      4 int cnt[1000];//S到某点最短路径的数目
      5 int low[1000];//S到某点最短路径长度
      6 int high[1000] = { 0 };//储存最短路径中前一结点救援队集结数的最大值
      7 int weight[1000];//某结点集结队数目
      8 int g[1000][1000];
      9 int front[1000];//最短路径中前驱结点
     10 int final[1000] = { 0 };//某结点是否处理完毕,处理完置1
     11 int N, M, S, D;
     12 void print();    
     13 int main()
     14 {
     15     cin >> N >> M >> S >> D;
     16         for(int i=0;i<N;i++)cnt[i]=1;
     17         /*cnt需要初始化为1,因为当没有其他最短路径的时候,cnt的值没有机会被修改,
     18         也就是默认值,那么就应该为1,不应初始化为0*/
     19     for (int i = 0; i < N; i++)
     20     {
     21         for (int j = 0; j < N; j++)
     22         {
     23             g[i][j] = infinity;
     24         }
     25         low[i] = infinity;
     26     }
     27     for (int i = 0; i < N; i++)
     28         cin >> weight[i];
     29     for (int i = 0; i < M; i++)
     30     {
     31         int a, b, c;
     32         cin >> a >> b >> c;
     33         g[a][b] = g[b][a] = c;
     34     }
     35     for (int i = 0; i < N; i++)
     36     {
     37         low[i] = g[0][i];
     38     }
     39     for (int i = 0; i < N; i++)
     40     {
     41         if (g[S][i] != infinity)
     42         {
     43             low[i] = g[S][i];
     44             front[i] = S;
     45             high[i] = weight[S];
     46         }
     47     }
     48     front[S] = -1;
     49     final[S] = 1;
     50     low[S] = 0;
     51     int k;
     52 //以下是dijkstra算法的实现
     53     for (int i = 0; i < N; i++)
     54     {
     55         int min = infinity;
     56         for (int j = 0; j < N; j++)
     57         {
     58             if (low[j] < min && !final[j])
     59             {
     60                 min = low[j];
     61                 k = j;
     62             }
     63         }
     64         high[k] = high[front[k]] + weight[front[k]];
     65         final[k] = 1;
     66         for (int w = 0; w < N; w++)
     67         {
     68             if (!final[w] && min + g[k][w] < low[w])
     69             {
     70                 cnt[w]=cnt[k];
     71                 low[w] = min + g[k][w];
     72                 front[w] = k;
     73                 high[w] = high[k] + weight[k];
     74             }
     75             else if (!final[w] && min + g[k][w] == low[w])/*else不能漏掉,因为low[w]在上一步改变了,有可能上下两个条件都符合,就会出现错误*/
     76             {
     77                 cnt[w]+=cnt[k];//即使权值没有比原来大,也需要增加最短路径数
     78                 if(high[k] + weight[k] > high[w])
     79                 {
     80                     front[w] = k;
     81                     high[w] = high[k] + weight[k];
     82                 }
     83             }
     84         }
     85     }
     86     print();
     87     return 0;
     88 }
     89 void print()
     90 {    
     91     cout << cnt[D]<<' ';
     92     cout << high[D]+weight[D] << endl;
     93     int s[1000];
     94     int r=-1;
     95     while (D!=-1)//需要利用堆栈输出
     96     {
     97         s[++r] = D;
     98         D = front[D];
     99     }
    100     while (r != -1)
    101     {//注意处理最后面的空格
    102         if (r == 0)cout << s[r--];
    103         else cout << s[r--] << ' ';
    104     }
    105 }        
  • 相关阅读:
    正则表达式学习《一》
    vs2008添加模板方法
    MongoDB学习笔记《二》
    oracle存储过程错误分析
    最近一个星期的学习,比较杂乱
    C#中的委托和事件
    c++随机数字
    Delphi中的接口
    C# 泛型
    LoadString、LoadIcon和LoadCursor函数
  • 原文地址:https://www.cnblogs.com/2020R/p/12724703.html
Copyright © 2020-2023  润新知