【pat】1003 Emergency 关于测试用例2、3、4的一点想法

这篇博客探讨了一位城市紧急救援队队长如何利用特殊地图规划最短路径以快速响应其他城市的紧急呼叫。文章通过示例展示了如何计算到达目的地的最短路径,并在途中动员尽可能多的救援队伍。算法考虑了城市之间的道路长度和每个城市的救援队数量,旨在实现救援效率的最大化。

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

1003 Emergency

As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road between any pair of cities are marked on the map. When there is an emergency call to you from some other city, your job is to lead your men to the place as quickly as possible, and at the mean time, call up as many hands on the way as possible.

在这里插入图片描述
在这里插入图片描述

基本用例:

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

其他2:

测试点2、4

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

输出

3 9

其他3:

测试点2、4

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

输出:

3 4

在这里插入图片描述

其他4:

输入:

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

输出:

2 4

实现代码:

100%pass


#include <iostream>
#include<vector>

using namespace std;
struct Path {
    int end;
    int length;
    Path(int end, int length) :end(end), length(length) {}
};


void getPathsAndMinLength(int start, int end, int citys, vector<Path>* graph, vector<int>* teams) {
    bool* visited = new bool[citys];
    //设置为未访问
    for (int i = 0; i < citys; i++)
    {
        visited[i] = false;
    }
    // 初始化当前路径
    int* pathLength = new int[citys];
    vector<int>* pre = new vector<int>[citys];
    int* weight = new int[citys];
    int* num = new int[citys];
    for (int i = 0; i < citys; i++)
    {
        if (i == start)
        {
            pathLength[i] = 0;
            num[i] = 1;
            pre[i].push_back(start);
            weight[i] = (*teams)[i];
        }
        else {
            pathLength[i] = 0x3FFFFFFF;
            num[i] = 0;
            weight[i] = 0;
        }
    }
    for (int i = 0; i < graph[start].size(); i++)
    {
        pathLength[graph[start][i].end] = graph[start][i].length;
        pre[graph[start][i].end].push_back(start);
        weight[graph[start][i].end] = weight[start] + (*teams)[graph[start][i].end];
        num[graph[start][i].end] = num[start];
    }
    bool hasUnvisted = true;
    visited[start] = true;
    while (hasUnvisted)
    {
        hasUnvisted = false;
        if (visited[end] == true)
        {
            break;
        }
        // 选取当前最短的路径访问
        int minPath = 0X3FFFFFFF, nextNode = 0;
        for (int i = 0; i < citys; i++)
        {
            //未访问过而且当前到原点start的路径最短
            if (visited[i] == false && minPath > pathLength[i]) {
                minPath = pathLength[i];
                nextNode = i;
                hasUnvisted = true;
            }
        }
        if (hasUnvisted)
        {
            visited[nextNode] = true;
            // 如果还有没有访问,但是可以访问的点,则以这个点为中间点继续访问
            vector<Path> path = graph[nextNode];
            for (int i = 0; i < path.size(); i++)
            {
                // 如果没有访问过,
                if (visited[path[i].end] == false && path[i].length < 0x3FFFFFFF) {
                    if (pathLength[nextNode] + path[i].length < pathLength[path[i].end])
                    {
                        pathLength[path[i].end] = pathLength[nextNode] + path[i].length;
                        pre[path[i].end].clear();
                        pre[path[i].end].push_back(nextNode);
                        num[path[i].end] = num[nextNode];
                        weight[path[i].end] = weight[nextNode] + (*teams)[path[i].end];
                    }
                    else if (pathLength[nextNode] + path[i].length == pathLength[path[i].end])
                    {
                        // 遇到了相同长度的路径,经过更多的中间节点的救援队更好
                        if (weight[nextNode] + (*teams)[path[i].end] > weight[path[i].end])
                        {
                            weight[path[i].end] = weight[nextNode] + (*teams)[path[i].end];
                        }
                        num[path[i].end] += num[nextNode];
                        pre[path[i].end].push_back(nextNode);
                    }
                }
            }
        }
    }
    cout << num[end] << " " << weight[end] << endl;
}


int main()
{
    int citys, roads, now, toCity;
    cin >> citys >> roads >> now >> toCity;
    vector<int> teams;
    int team;
    for (int i = 0; i < citys; i++)
    {
        cin >> team;
        teams.push_back(team);
    }
    vector<Path>* graph = new vector<Path>[citys];
    int start, end, length;
    for (int i = 0; i < roads; i++)
    {
        cin >> start >> end >> length;
        graph[start].push_back(Path(end, length));
        graph[end].push_back(Path(start, length));
    }
    getPathsAndMinLength(now, toCity, citys, graph, &teams);

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值