• Floyd-例题-实现-我的第一篇博客


    https://www.cnblogs.com/lbssxz/p/11014911.html

    这是网上看到的题目,以上是原博主的解答和题目来源(没找到别的题目来源)

    题目大意:

    城市交通费
    【问题描述】
    有 n 个城市,编号 1~n。其中 i 号城市的繁华度为 pi。省内有 m 条可以双向同行的高速
    公路,编号 1~m。编号为 j 的高速公路连接编号为 aj 和 bj 两个城市,经过高速公路的费用
    是 wj。若从城市 x 出发到某城市 y,除了需要缴纳高速公路费用,还要缴纳“城市建设费”
    (为从 x 城市到 y 城市所经过的所有城市中繁华度的最大值,包括 x 和 y 在内)。
    现提出 q 个询问,每个询问给出一组 x 和 y,你需要回答从 x 出发到 y 城市,所需要的
    最低交通费(高速公路费+城市建设费)是多少。
    【输入】
    第一行三个整数 n,m,q。
    第二行 n 个整数,表示 p1~pn。
    接下来 m 行中,每行 3 个正整数,第 j 行包含 Aj,Bj,Wj。
    随后 Q 行每组两个正整数 x,y 表示一组询问。
    【输出】
    共 Q 行,为对 Q 个问题的回答:x 城市到 y 城市的最小交通费用。
    【样例输入】
    5 7 2
    2 5 3 3 4
    1 2 3
    1 3 2
    2 5 3
    5 3 1
    5 4 1
    2 4 3
    3 4 4
    1 4
    2 3
    【样例输出】
    8
    9
    【数据范围及约定】
    n≤250,m≤20000,Q≤10000,Pi≤10000,Wj≤2000,保证任意两个城市可以互相到达。

    ------------恢复内容结束------------

    显然这是一个最短路问题,但是即便是最短路,即便确定了思路是FLOYD,仍然有很多不一样的思路。以下为我的思路和原本错误的方向——更新的对象错误。

    很多最短路问题,出了模板题以外,难点就在于:

    1. 如何找到“最短”--的表示方式,最短可能有多种情况,可能有多个条件,像这题有多个因素变量,是否有优先权,是否在这之前需要贪心或者先排序操作。
    2. 路径的初始化问题,其他参数的初始化问题,需不需要中间变量做桥梁***
    3. 有了最短路的定义,该怎么操作“更新”也是个难题。本题的难点就在于更新——不同路径繁华度最大值总是会变,每次找到一条新路都需要检查和更新。
    4. 这一环也是最容易出现问题的一环——常见问题:
      • 更新的对象,找错/找漏(我一开始的问题)
      • 更新的办法有问题,不全面,更新的操作不全,需要分类讨论
      • 更新的时候没有考虑到连锁影响,是否需要回溯或者重来
      • 更新直接操作复杂,需要找中间桥梁+中间补充操作——原博主的办法
    5. 最短路只是题目中的一环,在这基础上还有别的算法需要综合使用。

    对于这个问题,原博主使用的方式是贪心排序繁华度,除了繁华度,最短路的数组,另外又找了一个数组代替最终消费,然后每次都用通过排序直接对应新繁华度代替,

    你会发现如果连续使用最短路,更新结果会变。因为更新是不统一的。(个人对原博主的解法还有疑问,以后再做补充)

    而我的办法比较老土,就是简单的模拟,繁华度另开一个数组,每次把原来的繁华度减掉,然后加上新的繁华度,从而得到最短,这个结果是不会变的。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <algorithm>
      4 #include <cmath>
      5 #include <cstring>
      6 #include <string>
      7 #include <limits.h>
      8 using namespace std;
      9 typedef long long ll;
     10 const ll INF = 0x3f3f3f3f3f3f3f3fLL;
     11 int a[255][255];
     12 int n=0;
     13 const int I=0x3f3f3f3f;
     14 int m=0;
     15 int q=0;
     16 int t[255];
     17 int p[255][255];//表示当前的最大繁华度
     18 void floy0() {
     19     //memset(a,0,sizeof(a));
     20 
     21     for(int k=1; k<=n; k++) {
     22         for(int j=1; j<=n; j++) {
     23             for(int i=1; i<=n; i++) {
     24                 /*
     25                         int d1=max(t[i],t[j]);
     26                         int d2=max(t[i],t[j]);
     27                         d2=max(d2,t[k]);
     28                         a[i][j]=a[j][i]=min(a[j][i]+d1,d2+a[j][k]+a[k][i]);*/
     29                 //上面这个式子错误在于,不是每次都加一次繁华度.
     30                 //而是最后得到ij之后加一次繁华度,每次应该更新这个繁华度
     31                 //更新的时候一减一加
     32                 //或者从一开始就从繁华度最大值最小优先筛选--排序贪心一次后再做
     33                 //存在更新不完全???
     34                 int l=0;
     35                 if(a[j][k]<I&&a[k][i]<I&&p[i][k]<I&&p[j][k]<I) {
     36                     if(a[i][j]<I) {
     37                         l=max(p[j][k],p[i][k]);
     38                         if(a[j][i]>((a[j][k]-p[j][k])+(a[k][i]-p[k][i])+l)) {
     39                             a[j][i]=(a[j][k]-p[j][k])+(a[k][i]-p[k][i])+l;
     40                             p[i][j]=p[j][i]=l;
     41                             cout<<j<<"-->"<<i<<": "<<j<<"-->"<<k<<"-->"<<i<<endl<<endl;
     42                         }
     43 
     44 
     45                     } else {
     46                         l=max(p[k][i],p[j][k]);
     47                         p[i][j]=p[j][i]=l;
     48                         a[i][j]=a[j][i]=(a[j][k]-p[j][k])+(a[k][i]-p[k][i])+l;
     49                         cout<<j<<"-->"<<i<<": "<<j<<"-->"<<k<<"-->"<<i<<endl<<endl;
     50                     }
     51 
     52                 }
     53 
     54                 //比较的是最短路净值所以后面那个式子里的每个减完再加
     55 
     56 
     57                 for(int i=1; i<=n; i++) {
     58                     for(int j=1; j<=n; j++) {
     59                         if(a[i][j]>=I||a[i][j]<0)cout<<"!	";
     60                         else cout<<a[i][j]<<"	";
     61                     }
     62                     puts("");
     63                 }
     64                 puts("");
     65 
     66             }
     67         }
     68 
     69     }
     70 
     71 
     72 
     73 }
     74 
     75 
     76 int main () {
     77 
     78 
     79     scanf("%d%d%d",&n,&m,&q);
     80 
     81     memset(t,0,sizeof(t));
     82     memset(a,I,sizeof(a));
     83     memset(p,I,sizeof(p));
     84     for(int i=1; i<=n; i++) {
     85         scanf("%d",&t[i]);
     86         a[i][i]=t[i];
     87         p[i][i]=t[i];
     88     }
     89     while(m--) {
     90         int i,j,w;
     91         scanf("%d%d%d",&i,&j,&w);
     92         p[i][j]=p[j][i]=max(t[i],t[j]);
     93         a[i][j]=a[j][i]=w+p[i][j];
     94 
     95     }
     96 
     97     puts("");
     98     floy0();
     99     return 0;
    100 }
    老实一点,可爱多了
  • 相关阅读:
    csr_matrix参数解析
    SQL删除重复数据(根据多个字段),pandas的nan存入数据库报错
    XGBoost参数中文翻译以及参数调优
    pandas.DataFrame.quantile
    pandas.DataFrame.rank
    JOIN子句
    ORDER BY子句
    WHERE子句
    SELECT语句
    数据分析-基础
  • 原文地址:https://www.cnblogs.com/KID-yln/p/12466887.html
Copyright © 2020-2023  润新知