PAT甲级1003

本文介绍了一个基于Dijkstra算法的城市紧急救援调度问题解决方案。通过计算最短路径及其数量,该算法能够在多个城市间寻找到达目标地点的最快路线,并计算途中能够集结的最大救援力量。程序实现了路径搜索、救援队数量统计等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目翻译:

作为一个城市紧急援救队的指挥者,你得到了一个国家的特殊地图。地图上分散着几座城市,城市间用道路连接着。每个城市援救队的数量以及两座城市之间每条道路的长度已经在地图上标出。当某些城市发生了突发事件,需要你的帮助时,你的工作是带领你的队伍尽快的赶到事发现场,与此同时,召集尽可能多的在路上的队伍。

 

输入

每个输入文件包含一个测试实例。每个实例的第一行有四个正整数:N(<= 500)是城市的个数(城市的编号从0到N-1),M是道路的个数,C1和C2分别是你现在所在的城市以及你必须去救援的城市。下一行有N个整数,第i个整数是第i个城市中救援队的数量。然后下面有M行,每行表示一条道路。每一行有三个整数c1,c2和L,分别表示道路连接的两个城市以及道路的长度。保证C1到C2之间存在至少一条路径。

 

输出

对于每个测试实例,在一行中输出两个数字:C1和C2之间不同的最短路径的个数,你能聚集起来的最多的救援队数量。

一行中的所有数字必须被一个空格分隔开,在每行的结尾不允许出现空格。

 

样例输入

5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1

样例输出

2 4

以下为答案源码:

#include<iostream>
using namespace std;
#define MaxCityNum 501
#define MaxRoadLength 999999999


int ddistance[MaxCityNum][MaxCityNum],citynum,roadnum,from,to;//城市之间距离,城市数量,路的数量,出发点,目的地
int dis[MaxCityNum],teamnum[MaxCityNum],waynum[MaxCityNum],sum[MaxCityNum];//最短距离,救援队数量,最短路径数量,可收集的最大救援队数量
bool visited[MaxCityNum];//记录城市是否被访问
//Dijkstra算法找最短路径
void Dis()
{
    int i,j;
    for(i=0;i<citynum;i++)
    {
        dis[i]=ddistance[from][i];
        visited[i]=false;
    }
    dis[from]=0;
    visited[from]=true;
    sum[from]=teamnum[from];
    for(i=1;i<citynum;i++)
    {
        int u=-1;
        int mindis=MaxRoadLength;
        for(j=0;j<citynum;j++)
        {
            if(visited[j]==false&&dis[j]<mindis)
            {
                mindis=dis[j];
                u=j;
            }
        }
        if(u==-1) break;
        visited[u]=true;
        for(j=0;j<citynum;j++)
        {
            if((visited[j]==false)&&(dis[j]==dis[u]+ddistance[u][j]))
            {
                waynum[j]=waynum[j]+waynum[u];
                if(sum[j]<sum[u]+teamnum[j])
                {
                    sum[j]=sum[u]+teamnum[j];
                }
            }
            if((visited[j]==false)&&(dis[j]>dis[u]+ddistance[u][j]))
            {
                dis[j]=dis[u]+ddistance[u][j];
                waynum[j]=waynum[u];
                sum[j]=sum[u]+teamnum[j];

            }
        }
    }
}

int main()
{
    int i,j;
    int x,y,z;

    cin>>citynum>>roadnum>>from>>to;
    for(i=0;i<citynum;i++)
        cin>>teamnum[i];
    for(i=0;i<citynum;i++)
        for(j=0;j<citynum;j++)
        {
            if(i==j)
                ddistance[i][j]=0;
            else
                ddistance[i][j]=ddistance[j][i]=MaxRoadLength;
        }

    for(i=0;i<roadnum;i++)
    {
        cin>>x>>y>>z;
        ddistance[x][y]=ddistance[y][x]=z;
    }
    for(i=0;i<citynum;i++)
    {
         visited[i]=false;
         waynum[i]=1;
         sum[i]=teamnum[from]+teamnum[i];
    }
    Dis();
    cout<<waynum[to]<<" "<<sum[to];
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值