• PTA1003


    题意

    第一行给出四个数,分别代表城市数量(0 ~ n-1)、道路数量m、起点s、终点t。

    第二行给出n个数,代表第i个城市救援队的数量

    接下去给出m行,每行给出三个数x、y、z,表示x->y 距离z,是双向路。

    最后让我们输出s->t的最短路条数 和 能聚集到的救援队的最大数量。

    思路

    本题是一个Dijkstra的变形,变形的部分就是下面的关键部分代码。

    我们开两个数组保存结果,分别是ans1和ans2,

    ans1:起点s到每个点最短路的数量 ans2:起点s到每个点(在距离最短的情况下)最多救援几支队伍。

    但是要非常非常非常注意的一点就是:book数组标记的时候,book[s]=0而不是等于1,因为如果题目给出来的起点s和终点t恰好是同一个点,那么也是存在一条路线的。这个会造成样例答案都不对。

    关键部分代码:

        if(!book[j])
        {
            if(dis[k]+e[k][j]<dis[j]) // 找到一条更短的路
            {
                dis[j]=dis[k]+e[k][j];
                ans1[j]=ans1[k]; // 更新ans1:起点s到每个点最短路的数量
                ans2[j]=ans2[k]+num[j];
            }
            else if(dis[k]+e[k][j]==dis[j]) // 如果最短路路径相等
            {
                ans1[j]=ans1[j]+ans1[k];
                if(ans2[k]+num[j]>ans2[j])
                    ans2[j]=ans2[k]+num[j];
            }
        }
    

    AC代码

    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<stdio.h>
    
    using namespace std;
    typedef long long ll;
    #define inf 0x3f3f3f3f
    
    //5 6 0 2 城市数量0~n-1 路数量m s t
    //1 2 1 5 3 n个数 第i个城市救援队的数量
    //m行 x->y 距离z 双向路
    //0 1 1
    //0 2 2
    //0 3 1
    //1 2 1
    //2 4 1
    //3 4 1
    //output:
    //s->t的最短路条数 能聚集到的救援队的最大数量
    
    const int N=550;
    int e[N][N],dis[N],num[N],n,m,s,t,ans1[N],ans2[N];
    //ans1:起点s到每个点最短路的数量   ans2:起点s到每个点(在距离最短的情况下)最多救援几支队伍
    bool book[N];
    
    void dijkstra()
    {
        ans1[s]=1,ans2[s]=num[s]; // 最短路肯定有起码有一条,救援队数量起码有本身的数量(理解有问题)
        for(int i=0;i<n;i++)
            dis[i]=e[s][i]; // dis[i]=inf;
        //book[s]=1; 重要易错点 起点不能标记,因为起点自身到自身也是一条路径
        dis[s]=0;
        for(int i=0;i<n;i++)
        {
            int mi=inf,k;
            for(int j=0;j<n;j++)
            {
                if(!book[j]&&dis[j]<mi)
                    k=j,mi=dis[j];//book[j]=1;
            }
            book[k]=1;
            for(int j=0;j<n;j++)
            {
                if(!book[j])
                {
                    if(dis[k]+e[k][j]<dis[j]) // 找到一条更短的路
                    {
                        dis[j]=dis[k]+e[k][j];
                        ans1[j]=ans1[k]; // 更新ans1:起点s到每个点最短路的数量
                        ans2[j]=ans2[k]+num[j];
                    }
                    else if(dis[k]+e[k][j]==dis[j]) // 如果最短路路径相等
                    {
                        ans1[j]=ans1[j]+ans1[k];
                        if(ans2[k]+num[j]>ans2[j])
                            ans2[j]=ans2[k]+num[j];
                    }
                }
            }
        }
    }
    
    int main()
    {
        cin>>n>>m>>s>>t;
        for(int i=0;i<n;i++)
            cin>>num[i];
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(i==j)
                    e[i][j]=0;
                else
                    e[i][j]=inf;
            }
        }
        for(int i=0;i<m;i++)
        {
            int x,y,z;
            cin>>x>>y>>z;
            if(z<e[x][y]||z<e[y][x])
                e[x][y]=e[y][x]=z;
        }
        dijkstra();
        cout<<ans1[t]<<" "<<ans2[t];
        return 0;
    };
    
  • 相关阅读:
    CF343D Water Tree
    CF340B Maximal Area Quadrilateral
    测试环境/生产环境,接口地址配置
    json-server MOCK方案
    vscode prettier保存代码时自动格式化
    蓝鲸6.0前置准备
    nginx日志提取案列
    蓝鲸模拟考试
    部署维护
    第一次模拟考
  • 原文地址:https://www.cnblogs.com/OFSHK/p/14448818.html
Copyright © 2020-2023  润新知