• PTA L2-001 紧急救援


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

    题目大意:就是让你找一个单源最短路,同时还需要能够输出最短路的路径

    输入:

    第一行n,m,s,d,分别是城市数,路径数,起点,终点。

    第二行n个数,是每个城市有的救援队的数目

    接下来m行就是每条道路的两个端点和长度

    输出:

    第一行输出最短路径条数和救援队数量,第二行就是从起点到终点的路径。

    分析:本质上还是用dij做的最短路问题,但需要添加些东西,我们可以用num数组表示从起点到i的最短路径条数,w数组表示救援队数量

    同时最用dij做最短路的时候,把最短路径上每个城市的前驱用pre数组记录下来

    这样,在更新最短路时,如果dis[e.to]>dis[v]+e.cost  就需要将v和e.to连接起来,那么num[e.to]就应该和num[v]保持一致,w[e.to]=w[v]+a[e.to]

    除了大于的情况,对于dis[e.to]==dis[v]+e.cost,我们也需要考虑,因为e.to的最短路径条数除了本身的,还有从v连接过来的,则num[e.to]+=num[v]

    如果w[v]+a[e.to]>w[e.to],那么w[e.to]=w[v]+a[e.to],因为要保证救援队数量最多

    另外每当连路径的时候记得把pre数组录入一下,最后递归输出即可

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int inf=1<<30;
     4 typedef long long ll;
     5 typedef pair<int,int> P;
     6 const double pi=acos(-1);
     7 const int mod=1e8+7;
     8 const int maxn=505;
     9 const int maxm=6300;
    10 int dis[maxn];
    11 int a[maxn],num[maxn],w[maxn],pre[maxn];//num数组是出发点到i点时拥有的路径的条数,w数组是救援队的数目 
    12 struct edge{
    13     int to,cost;
    14 };
    15 int x,y,z,n,m,s,d;
    16 vector<edge> g[maxm];
    17 void dij(int s){
    18     priority_queue<P,vector<P>,greater<P> > que;
    19     fill(dis,dis+maxn,inf);
    20     dis[s]=0;
    21     w[s]=a[s],num[s]=1;//初始化,到起始点救援队数量就是起始点本身救援队数量,路径也只有一条 
    22     que.push({0,s});
    23     while(!que.empty()){
    24         P p=que.top();que.pop();
    25         int v=p.second;
    26         if(dis[v]<p.first) continue;
    27         for(int i=0;i<g[v].size();i++){
    28             edge e=g[v][i];
    29             if(dis[e.to]>dis[v]+e.cost){//这种情况肯定要从v到e.to了 
    30                 num[e.to]=num[v];
    31                 w[e.to]=w[v]+a[e.to]; 
    32                 dis[e.to]=dis[v]+e.cost;
    33                 pre[e.to]=v;
    34                 que.push({dis[e.to],e.to});
    35             }
    36             else if(dis[e.to]==dis[v]+e.cost){
    37                 if(w[v]+a[e.to]>w[e.to]){w[e.to]=w[v]+a[e.to];pre[e.to]=v;} 
    38                 num[e.to]+=num[v];    //还要再加上v点的            
    39             }
    40         }
    41     }
    42 }
    43 void print(int c){
    44     if(c==s){
    45         cout<<s;return;
    46     }
    47     print(pre[c]);
    48     cout<<" "<<c;
    49 }
    50 int main(){
    51     scanf("%d%d%d%d",&n,&m,&s,&d);
    52     for(int i=0;i<n;i++) scanf("%d",&a[i]);
    53     for(int i=0;i<m;i++){
    54         scanf("%d%d%d",&x,&y,&z);
    55         g[x].push_back({y,z});
    56         g[y].push_back({x,z});
    57     }
    58     dij(s);
    59     cout<<num[d]<<" "<<w[d]<<endl;
    60     print(d);
    61     cout<<endl;
    62     return 0;
    63 }
  • 相关阅读:
    Building a flexiable renderer
    Indirect Illumination in mental ray
    我的心情
    Cellular Automata
    Subsurface Scattering in mental ray
    Shader Types in mental ray
    BSP Traversal
    我的渲染器终于达到了MR的速度
    How to handle displacement and motion blur
    说明
  • 原文地址:https://www.cnblogs.com/qingjiuling/p/10474820.html
Copyright © 2020-2023  润新知