zoukankan      html  css  js  c++  java
  • 最短路径问题【浙大10年机试真题】 Dijkstra算法求单源最短路径

    昨天下午的热身赛D题---《旅游啦》,刚开始以为是要先求单源最短路径,于是呼呼啦啦把DJ的算法搬出来实现,完了后才发现不需要这么做,题目其实是想考察图的最优代价深度优先搜索,无奈最后卡在了回溯时的代价求和。

    那道题以后再去A掉,现在先写这个最短路径,关于图的各种应用算法,考研时也要求掌握,不过离上机实现还差一点,Dj的算法实际就是贪心在图论中的应用,使用final[i]记录编号为i的结点此时是否和源点在同一集合中,使用dist[i]记录从源点到i结点的当前最短路径长度,不过这道题另外增加了路径花费,于是把dist封装成结构体,这无关技术,不必赘述,用pre[i]记录寻找到i结点时的前置结点,可根据该数组顺藤摸瓜,最终构造出整条路径,这道题只要求求dist值,所以pre数组可以省略。

    算法刚开始时,将final[s](s为源点)置为1,其余结点的final值置为0,将dist[i]的值初始化为e[s][i],不相连的话以-1代替,因为不知道OJ上int的最大值,以-1更保险。初始化完成,在dist中寻找满足以下两个条件的结点j:1.final[j] == 0; 2. dist[j]值最小。这个点即为该轮循环找到的最佳跳点,并入集合中,即final[j]置为1,以j结点为跳点,更新dist数组中所有未并入集合中的结点,如果dist[i] > dist[j] + e[j][i](当然前提是j需要与i直接连通), 则将dist[i]更新为dist[j] + e[j][i]。循环上述"跳点--更新dist--更新跳点"的过程,直至需要寻找的终点t并入集合中,算法结束,直接输出dist[t]即可AC。

    以下是代码,内存开大是为了方便操作,用动态分配内存的方法可以压缩掉多余的开销:

      1 #include <stdio.h>
    2 #include <stdlib.h>
    3
    4 typedef struct{
    5 int d;
    6 int p;
    7 }edge;
    8
    9 edge e[1000][1000];
    10 int final[1000];//该点是否和源点属于同一集合
    11 edge dist[1000];//记录从源点到其他个各顶点当前最短路径长度和最小花费
    12
    13 int main()
    14 {
    15 long n,m;
    16 int temp1,temp2,temp3,temp4;
    17 long i,j;
    18 int s,t;
    19 int minlength,minprice,templength,tempprice;
    20 int jump;//跳点
    21 while(scanf("%ld %ld",&n,&m) != EOF && (n != 0 || m != 0))
    22 {
    23 for(i =0; i < n; i ++)
    24 {
    25 for(j = 0; j < n; j ++)
    26 {
    27 e[i][j].d = -1;
    28 e[i][j].p = -1;
    29 }
    30 }
    31 for(i = 0; i < n; i ++)
    32 {
    33 final[i] = 0;
    34 }
    35 for(i = 0; i < m; i ++)
    36 {
    37 scanf("%d %d %d %d",&temp1,&temp2,&temp3,&temp4);
    38 e[temp1 - 1][temp2 - 1].d = temp3;
    39 e[temp1 - 1][temp2 - 1].p = temp4;
    40 e[temp2 - 1][temp1 - 1].d = temp3;
    41 e[temp2 - 1][temp1 - 1].p = temp4;
    42 }
    43 scanf("%d %d",&s,&t);
    44 final[s - 1] = 1;
    45 for(i = 0; i < n; i ++)
    46 {
    47 dist[i].d = e[s - 1][i].d;
    48 dist[i].p = e[s - 1][i].p;
    49 }
    50 jump = s - 1;
    51 while(final[t - 1] != 1)//t结点未并入集合中
    52 {
    53 for(i = 0; i < n; i ++)
    54 {
    55 if(final[i] != 1)
    56 {
    57 minlength = dist[i].d;
    58 minprice = dist[i].p;
    59 if(jump != s - 1)
    60 {
    61 if(e[jump][i].d != -1)
    62 {
    63 templength = dist[jump].d + e[jump][i].d;
    64 tempprice = dist[jump].p + e[jump][i].p;
    65 if(templength != -1)
    66 {
    67 if(minlength == -1 || (minlength > templength) || (minlength == templength && minprice > tempprice))
    68 {
    69 minlength = templength;
    70 minprice = tempprice;
    71 }
    72 }
    73 }
    74 }
    75 dist[i].d = minlength;
    76 dist[i].p = minprice;
    77 }
    78 }
    79
    80 temp1 = dist[0].d;
    81 temp2 = dist[0].p;
    82 temp3 = 0;
    83 for(i = 1; i < n; i ++)
    84 {
    85 if(dist[i].d == -1 || final[i] == 1)
    86 {
    87 continue;
    88 }
    89 else if(final[temp3] == 1 || temp1 == -1 || dist[i].d < temp1 || (dist[i].d == temp1 && dist[i].p < temp2))
    90 {
    91 temp1 = dist[i].d;
    92 temp2 = dist[i].p;
    93 temp3 = i;
    94 }
    95 }
    96 final[temp3] = 1;
    97 jump = temp3;
    98 }
    99 printf("%d %d\n",dist[t - 1].d, dist[t - 1].p);
    100 }
    101 return 0;
    102 }
    103 /**************************************************************
    104 Problem: 1008
    105 User: qiushuiruyan
    106 Language: C
    107 Result: Accepted
    108 Time:20 ms
    109 Memory:8732 kb
    110 ****************************************************************/


    多说一下:关于最短路径问题,有SPFA算法更加有效,而且,该算法是由西南交通大学段凡丁于1994年发表的,有空去学习学习^_^

  • 相关阅读:
    C#磁吸屏幕窗体类库
    准备
    我写的诗
    How to turn off a laptop keyboard
    How to tell which commit a tag points to in Git?
    Why should I care about lightweight vs. annotated tags?
    How to get rid of “would clobber existing tag”
    Facebook, Google and Twitter threaten to leave Hong Kong over privacy law changes
    The need for legislative reform on secrecy orders
    Can a foreign key be NULL and/or duplicate?
  • 原文地址:https://www.cnblogs.com/Rafy/p/2389814.html
Copyright © 2011-2022 走看看