• 交通网最短路径长 dp c++


     1 //
     2 // Created by Arc on 2020/4/26.
     3 //
     4 
     5 /*
     6  * 城市交通线路,单向通行,道路之间可能有不通,每条连同的路之间都有相应的费用
     7  * 求从起点到终点的最小费用
     8  *
     9  * 需要一个a[n][n]数组存放每条路的费用,不连同就为0(给不连同加一个特判吧)
    10  * f[n]表示点i到终点的最小费用,初始值都设为1000000(求最小费用,那你肯定要找个最大值啊)
    11  * c[i]存放的是它的下一个的下标(画重点,这种方法真的很常见)
    12  */
    13 
    14 #include <bits/stdc++.h>
    15 using namespace std;
    16 int main(){
    17     long long f[100],c[100],a[100][100];//底下所有的下标都是从1开始的!!!!attention please!
    18     int n;//总数
    19     cin>>n;
    20     memset(a,0, sizeof(a));
    21     memset(c,0,sizeof(c));
    22     for (int i = 1; i <= n; ++i) {//下标是从1开始的所以是<=n
    23         for (int j = 1; j <= n; ++j) {
    24             cin >> a[i][j];
    25 
    26         }
    27     }
    28         for (int k = 1; k < n; ++k) {
    29             f[k]=1000000;
    30 
    31         }
    32 
    33         //这里是算法的主体:逆推
    34         f[n]=0;
    35         /*
    36          * 写的时候是从n-1开始的,然后挨个往后比较
    37          *(某dl说有点像冒泡排序bubblesort,好像确实有点哈哈哈哈)
    38          * 就比如 1 2 3 4 5 就是从4开始往后跟5比
    39          * 然后3开始跟4,5比
    40          * 这里我把3称为固定点,4和5就是跳跃点(方便说明起见,完全杜撰的!)
    41          */
    42         for (int i = n-1; i >= 1; i--) {//写的时候是从n-1开始的,然后挨个往后比较
    43             for (int j = i+1; j <= n; ++j) {//<=n
    44                 /*解释一下底下这行:
    45                  * a[i][j]>0 就是刚刚说的那个特判嘛,判断有没有相连
    46                  * f[j]!=1000000 f[j]是正在比较的那一个跳跃点,它要是为1000000那说明它根本不能到终点啊
    47                  * f[i]>a[i][j]+f[j] 一开始肯定成立,因为f[i]初始为1000000,到后来的时候,如果它大,那就是要改了呗
    48                  * f[i]=a[i][j]+f[j]; 更该成比较小的值
    49                  * c[i]=j;把这个位置记录下来
    50                  *
    51                  * 所以要赋值,需要满足的条件有:
    52                  * 1. i,j两点可以通
    53                  * 2. j能连接终点
    54                  * 3. 固定点的f比原来那个要小
    55                  */
    56                 if((a[i][j]>0) && (f[j]!=1000000) && (f[i]>a[i][j]+f[j]) ){
    57                     f[i]=a[i][j]+f[j];
    58                     c[i]=j;
    59                 }
    60 
    61                // if(i==1 && j==n){
    62                   //  cout<<"minlong="<<f[1]<<endl;//max
    63                 //}
    64 
    65             }
    66 
    67         }
    68         //输出
    69          cout<<"minlong="<<f[1]<<endl;//max
    70         int x=1;
    71         while(x!=0){//注意这个条件,x为0的时候就不需要输出了
    72             cout<<x<<" ";
    73             x = c[x];
    74 
    75         }
    76 
    77 
    78 
    79 
    80     return 0;
    81 
    82 }

    给一点点样例

    Print in:
    10
    0
    2 5 1 0 0 0 0 0 0 0 0 0 0 12 14 0 0 0 0 0 0 0 0 6 10 4 0 0 0 0 0 0 0 13 12 11 0 0 0 0 0 0 0 0 0 0 3 9 0 0 0 0 0 0 0 0 6 5 0 0 0 0 0 0 0 0 0 10 0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0

    Print out:
    minlong=19
    1 3 5 8 10

    说一下小白在这个代码中的一点点有点尴尬的错误:括号匹配问题.有时换编译器(编辑器)换多了就容易混:它有没有自动补全来着??中括号还好,大括号就会出现一堆bug,因为中括号小括号它自动补全了以后再往上码它也只是跳过它,但是大括号...码一个是一个!

     最后一句:我原来这么长时间没有写题解了哈哈哈哈,抓住四月的小尾巴干起来!

  • 相关阅读:
    杭电2059
    杭电2058
    php错误大集合
    显示IP地址
    超简单好用的屏幕录像工具
    jquery“不再提醒"功能
    KindEditor编辑器中的class自动过滤了
    实用案例:切换面板同时切换内容
    仿51返利用户图解教程
    JavaScript调用dataTable并获取其值(ASP.Net,VS2005)
  • 原文地址:https://www.cnblogs.com/zhmlzhml/p/12784381.html
Copyright © 2020-2023  润新知