• HDOJ-3790-最短路径问题 解题报告


           一道最短路问题。普通最短路问题的边只有一种权值,而此题的边要考虑两种权值。因为节点n<=1000,所以不能够使用Floyd算法,时间复杂度较高,这里使用Dijkstra算法解决。


           中文描述,题意不再赘述。只是要注意每条边都有距离和花费两种权,当且仅当两条边的距离相等时才比较花费。因为需要考虑两种权,所以算法代码要有相应的改变。另外,要考虑重边的问题,依旧要考虑两种权值。


           下面是解题代码:Dijkstra解法

      1 #include <stdio.h>
      2 #define N 1001
      3 #define INF 9999999
      4 
      5 int map[N][N];      /*距离图*/
      6 int cost[N][N];     /*花费图*/
      7 int dis[N];         /*起点到i的距离*/
      8 int cos[N];         /*起点到i的花费*/
      9 int flag[N];        /*标志变量*/
     10 int n, m;
     11 int s, t;
     12 
     13 void Init();    /*初始化*/
     14 
     15 void Read();    /*输入*/
     16 
     17 void Dijkstra();
     18 
     19 int main()
     20 {
     21     while (~scanf("%d %d", &n, &m))
     22     {
     23         if (n == 0 && m == 0)
     24         {
     25             break;
     26         }
     27         Init();
     28         Read();
     29         Dijkstra();
     30         printf("%d %d
    ", dis[t], cos[t]);
     31     }
     32     return 0;
     33 }
     34 
     35 void Init()     /*初始化*/
     36 {
     37     int i, j;
     38     for (i=1; i<=n; ++i)
     39     {
     40         for (j=1; j<=n; ++j)
     41         {
     42             map[i][j] = cost[i][j] = INF;
     43         }
     44         dis[i] = cos[i] = INF;
     45         flag[i] = 0;
     46     }
     47     return;
     48 }
     49 
     50 void Read()     /*输入*/
     51 {
     52     int i;
     53     int a, b, c, d;
     54     for (i=0; i<m; ++i)
     55     {
     56         scanf("%d %d %d %d", &a, &b, &c, &d);
     57         if (map[a][b] > c || (map[a][b] == c && cost[a][b] > d))    /*解决重边*/
     58         {
     59             map[a][b] = map[b][a] = c;
     60             cost[a][b] = cost[b][a] = d;
     61         }
     62     }
     63     scanf("%d %d", &s, &t);
     64     return;
     65 }
     66 
     67 void Dijkstra()
     68 {
     69     int i, j, k;
     70     int mind, minc;
     71     dis[s] = cos[s] = 0;
     72     for (i=1; i<=n; ++i)
     73     {
     74         mind = minc = INF;
     75         for (j=1; j<=n; ++j)
     76         {
     77             /*多权值的比较*/
     78             if (flag[j] == 0 && (mind > dis[j] || (mind == dis[j] && minc > cos[j])))
     79             {
     80                 mind = dis[k = j];
     81                 minc = cos[k];
     82             }
     83         }
     84         flag[k] = 1;
     85         for (j=1; j<=n; ++j)
     86         {
     87             if (flag[j] == 0 && dis[j] > dis[k] + map[k][j])
     88             {
     89                 dis[j] = dis[k] + map[k][j];
     90                 cos[j] = cos[k] + cost[k][j];
     91             }
     92             /*当距离相同时考虑花费*/
     93             if (flag[j] == 0 && dis[j] == dis[k] + map[k][j] && cos[j] > cos[k] + cost[k][j])
     94             {
     95                 cos[j] = cos[k] + cost[k][j];
     96             }
     97         }
     98     }
     99     return;
    100 }
  • 相关阅读:
    【技术贴】每次打开excel表格都会弹出新excel。book1.xls解决方法
    【技术贴】鼠标右键盘符属性报错Volume filter WMI not found的解决办法
    解决QQ聊天QQ秀咒语为什么我不能施放咒语/看不到咒语效果?
    【java】servlet输出pdf文件到浏览器 教程
    C#抽象工厂模式的几种实现方法及比较(外摘)
    SQL 语句汇总With子句
    浅析.NET开发中代理模式的使用(外摘)
    使用设计模式构建通用数据库访问类(外摘)
    Cognos产品组件及各组件功能介绍
    游标Oracle游标汇总
  • 原文地址:https://www.cnblogs.com/JZQT/p/3802445.html
Copyright © 2020-2023  润新知