• pta l3-7(天梯地图)


    题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805051153825792

    题意:给定n个地点,m条边以及边的信息,给出起点s,终点d,求s到d的最快距离,不唯一时取距离最短的,还要求s到d的最短距离,不唯一时取经过结点数最少的,若这两条路线重合,输出一条即可。

    思路:两次dijkstra算法,第一次的两个维度是时间tim,距离len,用pre1记录路径; 第二次的两个维度是距离len,经过结点数num,用pre2记录路径。为了便于比较两条路径是否一致,可将其存在vector中,直接用‘==’判断即可,然后按照要求输出(代码看着挺长,其实两次dijkstra差不多)。

    AC代码:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 const int maxn=505;
      5 const int inf=0x3f3f3f3f;
      6 int n,m,s,d;
      7 int a[maxn][maxn],b[maxn][maxn],tim[maxn],len[maxn],num[maxn],vis1[maxn],vis2[maxn],pre1[maxn],pre2[maxn];
      8 vector<int> v1,v2;
      9 
     10 void dijkstra1(){
     11     len[s]=tim[s]=0;
     12     for(int i=0;i<n;++i){
     13         int k,Min=inf;
     14         for(int j=0;j<n;++j)
     15             if(!vis1[j]&&tim[j]<Min)
     16                 k=j,Min=tim[j];
     17         if(Min==inf) break;
     18         vis1[k]=1;
     19         for(int j=0;j<n;++j)
     20             if(!vis1[j]&&tim[j]>tim[k]+b[k][j]){
     21                 tim[j]=tim[k]+b[k][j];
     22                 len[j]=len[k]+a[k][j];
     23                 pre1[j]=k;
     24             }
     25             else if(!vis1[j]&&tim[j]==tim[k]+b[k][j]&&len[j]>len[k]+a[k][j]){
     26                 len[j]=len[k]+a[k][j];
     27                 pre1[j]=k;
     28             }
     29     }
     30 }
     31 
     32 void dijkstra2(){
     33     len[s]=0,num[s]=1,pre2[s]=-1;
     34     for(int i=0;i<n;++i){
     35         int k,Min=inf;
     36         for(int j=0;j<n;++j)
     37             if(!vis2[j]&&len[j]<Min)
     38                 k=j,Min=len[j];
     39         if(Min==inf) break;
     40         vis2[k]=1;
     41         for(int j=0;j<n;++j)
     42             if(!vis2[j]&&len[j]>len[k]+a[k][j]){
     43                 len[j]=len[k]+a[k][j];
     44                 num[j]=num[k]+1;
     45                 pre2[j]=k;
     46             }
     47             else if(!vis2[j]&&len[j]==len[k]+a[k][j]&&num[j]>num[k]+1){
     48                 num[j]=num[k]+1;
     49                 pre2[j]=k;
     50             }
     51     }
     52 }
     53 
     54 void getv1(){
     55     int p=d;
     56     while(p!=-1){
     57         v1.push_back(p);
     58         p=pre1[p];
     59     }
     60 }
     61 
     62 void getv2(){
     63     int p=d;
     64     while(p!=-1){
     65         v2.push_back(p);
     66         p=pre2[p];
     67     }
     68 }
     69 
     70 int main()
     71 {
     72     scanf("%d%d",&n,&m);
     73     memset(a,0x3f,sizeof(a));
     74     memset(b,0x3f,sizeof(b));
     75     for(int i=0;i<n;++i)
     76         tim[i]=len[i]=inf,pre1[i]=-1;
     77     for(int i=0;i<m;++i){
     78         int t1,t2,flag,l,t;
     79         scanf("%d%d%d%d%d",&t1,&t2,&flag,&l,&t);
     80         a[t1][t2]=l,b[t1][t2]=t;
     81         if(!flag)
     82             a[t2][t1]=l,b[t2][t1]=t;
     83     }
     84     scanf("%d%d",&s,&d);
     85     dijkstra1();
     86     getv1();
     87     for(int i=0;i<n;++i)
     88         len[i]=num[i]=inf,pre2[i]=-1;
     89     dijkstra2();
     90     getv2();
     91     if(v1==v2){
     92         printf("Time = %d; Distance = %d: %d",tim[d],len[d],s);
     93         for(int i=v1.size()-2;i>=0;--i)
     94             printf(" => %d",v1[i]);
     95     }
     96     else{
     97         printf("Time = %d: %d",tim[d],s);
     98         for(int i=v1.size()-2;i>=0;--i)
     99             printf(" => %d",v1[i]);
    100         printf("
    ");
    101         printf("Distance = %d: %d",len[d],s);
    102         for(int i=v2.size()-2;i>=0;--i)
    103             printf(" => %d",v2[i]);
    104     }
    105     return 0;
    106 }
  • 相关阅读:
    第二节:简单工厂模式(静态工厂模式)
    第一节:不使用设计模式的传统方式
    第三章:设计模式概述
    第二节:类与类之间的关系
    高斯混合模型(GMM)
    随机森林
    LDA主题模型
    Adaboost算法
    线性代数
    k-means聚类
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/10601586.html
Copyright © 2020-2023  润新知