• HDOJ-2112-HDU Today 解题报告


           最短路问题,只是牵扯到了字符串的操作。题目是中文描述就不多说了。因为这道题不像普通的最短路问题以数字来给地点编号,而是以地点的名称来确定,所以更加结合实际问题,但是又不方便解题。那么应该把地点的名称用数字来编号,把名称转换成编号来解题,这才是关键。


           注意:此题中的路为无向的;如果无法从起点到达终点,输出为-1,这是题目没有说明的;如果起点就是终点,输出为0。此题用C或C++编译器的运行时间比GCC和G++短。


           下面是解题代码:Dijkstra解法

      1 #include <stdio.h>
      2 #include <string.h>
      3 #define N 151
      4 #define NAME 31
      5 #define INF 99999999
      6 
      7 int map[N][N];
      8 int dis[N];         //从起点到编号为下标的地点的距离
      9 int flag[N];
     10 char name[N][NAME];
     11 int na;     //站点的个数
     12 int n;      //道路的个数
     13 
     14 void Init();    //初始化
     15 
     16 void Read();    //输入
     17 
     18 int Count(char s[]);    //计算字符串对应的编号
     19 
     20 void Dijkstra();
     21 
     22 int main()
     23 {
     24     while (~scanf("%d", &n))
     25     {
     26         if (n == -1) break;
     27         Init();
     28         Read();
     29         Dijkstra();
     30         if (strcmp(name[1], name[0]) == 0)
     31         {
     32             printf("0
    ");
     33             continue;
     34         }
     35         printf("%d
    ", dis[1] == INF ? -1 : dis[1]);
     36     }
     37     return 0;
     38 }
     39 
     40 void Init()     //初始化
     41 {
     42     int i, j;
     43     for (i=0; i<N; ++i)
     44     {
     45         for (j=0; j<N; ++j)
     46         {
     47             map[i][j] = INF;
     48         }
     49         dis[i] = INF;
     50         flag[i] = 0;
     51     }
     52     scanf("%s %s", name[0], name[1]);
     53     na = 2;
     54     return;
     55 }
     56 
     57 void Read()     //输入
     58 {
     59     int i;
     60     char sa[NAME], sb[NAME];
     61     int a, b, c;
     62     for (i=0; i<n; ++i)
     63     {
     64         scanf("%s %s %d", sa, sb, &c);
     65         a = Count(sa);
     66         b = Count(sb);
     67         map[a][b] = map[b][a] = c;
     68     }
     69     return;
     70 }
     71 
     72 int Count(char s[])     //计算字符串对应的编号
     73 {
     74     int i;
     75     for (i=0; i<na; ++i)
     76     {
     77         if (strcmp(name[i], s) == 0)
     78         {
     79             return i;
     80         }
     81     }
     82     strcpy(name[na++], s);
     83     return (na - 1);
     84 }
     85 
     86 void Dijkstra()
     87 {
     88     int i, j, k;
     89     int min;
     90     dis[0] = 0;
     91     for (j=0; j<na; ++j)
     92     {
     93         min = INF;
     94         for (i=0; i<na; ++i)
     95         {
     96             if (flag[i] == 0 && min > dis[i])
     97             {
     98                 min = dis[k = i];
     99             }
    100         }
    101         flag[k] = 1;
    102         for (i=0; i<na; ++i)
    103         {
    104             if (flag[i] == 0 && dis[i] > dis[k] + map[k][i])
    105             {
    106                 dis[i] = dis[k] + map[k][i];
    107             }
    108         }
    109     }
    110     return;
    111 }

           接下来是Floyd解法,比Dijkstra解法耗时长,但是优势在于代码编写简单

     1 #include <stdio.h>
     2 #include <string.h>
     3 #define N 151
     4 #define NAME 31
     5 #define INF 9999999
     6 
     7 int map[N][N];
     8 char name[N][NAME];
     9 int na;     //站点的个数
    10 int n;      //道路的个数
    11 
    12 void Init();    //初始化
    13 
    14 void Read();    //输入
    15 
    16 int Count(char s[]);    //计算字符串对应的编号
    17 
    18 void Floyd();
    19 
    20 int main()
    21 {
    22     while (~scanf("%d", &n))
    23     {
    24         if (n == -1) break;
    25         Init();
    26         Read();
    27         Floyd();
    28         if (strcmp(name[1], name[0]) == 0)
    29         {
    30             printf("0
    ");
    31             continue;
    32         }
    33         printf("%d
    ", map[0][1] == INF ? -1 : map[0][1]);
    34     }
    35     return 0;
    36 }
    37 
    38 void Init()     //初始化
    39 {
    40     int i, j;
    41     for (i=0; i<N; ++i)
    42     {
    43         for (j=0; j<N; ++j)
    44         {
    45             map[i][j] = INF;
    46         }
    47     }
    48     scanf("%s %s", name[0], name[1]);
    49     na = 2;
    50     return;
    51 }
    52 
    53 void Read()     //输入
    54 {
    55     int i;
    56     char sa[NAME], sb[NAME];
    57     int a, b, c;
    58     for (i=0; i<n; ++i)
    59     {
    60         scanf("%s %s %d", sa, sb, &c);
    61         a = Count(sa);
    62         b = Count(sb);
    63         map[a][b] = map[b][a] = c;
    64     }
    65     return;
    66 }
    67 
    68 int Count(char s[])     //计算字符串对应的编号
    69 {
    70     int i;
    71     for (i=0; i<na; ++i)
    72     {
    73         if (strcmp(name[i], s) == 0)
    74         {
    75             return i;
    76         }
    77     }
    78     strcpy(name[na++], s);
    79     return (na - 1);
    80 }
    81 
    82 void Floyd()
    83 {
    84     int i, j, k;
    85     for (k=0; k<na; ++k)
    86     {
    87         for (i=0; i<na; ++i)
    88         {
    89             for (j=0; j<na; ++j)
    90             {
    91                 if (map[i][j] > map[i][k] + map[k][j])
    92                 {
    93                     map[i][j] = map[i][k] + map[k][j];
    94                 }
    95             }
    96         }
    97     }
    98     return;
    99 }
  • 相关阅读:
    hdu 1231 最大连续子序列
    数据加载初始化问题
    分页查询
    PHP-引入文件(include)后,页面错位,不居中解决办法
    数据库中的事务和锁(乐观、悲观锁,共享、排他锁,死锁)
    java操作excel 工具类
    微信公众号处理
    java实用资料
    【转】字符流和字节流的区别,使用场景,相关类
    基于redis分布式锁实现“秒杀”
  • 原文地址:https://www.cnblogs.com/JZQT/p/3802444.html
Copyright © 2020-2023  润新知