PAT(Advanced) 1003 Emergency (25)

两段代码分别使用Dijkstra算法求解从起点到终点的最短路径和队伍总数,以及考虑救援人数的最短路径和路径条数。代码中涉及城市间的路径矩阵、访问标记、最短路径长度和队伍数量等关键变量,通过遍历和更新策略找到最优解。
摘要由CSDN通过智能技术生成

2018/6/4

// 题目要求第一个输出是最短路径的个数
// Dijkstra变种

#include <iostream>
#include <climits>
using namespace std;

#define MAXN 500
int n, m, c1, c2;

int city[MAXN][MAXN];   // 各城市间路径
int team[MAXN];         // 各城市队伍数

int road[MAXN];         // 各城市到起点的道路数
int team_max[MAXN];     // 各城市到起点的最大队伍数
int len_min[MAXN];      // 各城市到起点的最短路径长
bool visit[MAXN];       // 该城市是否访问过

void Dijkstra(int start){
    fill(visit, visit + n, false);
    fill(len_min, len_min + n, INT_MAX);

    team_max[start] = team[start];
    len_min[start] = 0;
    road[start] = 1;

    int cur_min;
    int u;
    for(int i = 0; i < n; i++){
        cur_min = INT_MAX;

        // 找出到起点最近的点            当 i = 0 时, u就是起点
        for(int j = 0; j < n; j++){
            if(visit[j] == false && len_min[j] < cur_min){
                cur_min = len_min[j];
                u = j;
            }
        }

        visit[u] = true;

        // 更新其余点到起点的距离
        for(int j = 0; j < n; j++){
            if(visit[j] == false && city[u][j] != INT_MAX){ // 若INT_MAX定义为0x3f3f3f3f,则可取消判定是否等于INT_MAX,否则不判定的话会超INT范围; 是否判定j访问过都不影响结果
                // 若新加入的点u连接其余点后,其余点到起点的距离变短,则更新距离, 路径数为u的路径数
                if(len_min[u] + city[u][j] < len_min[j]){
                    road[j] = road[u];
                    len_min[j] = len_min[u] + city[u][j];
                    team_max[j] = team_max[u] + team[j];
                // 若相等,则到该点的路径为原有路径加上新加点u的路径
                }else if(len_min[u] + city[u][j] == len_min[j]){
                    road[j] += road[u];
                    if(team_max[j] < team_max[u] + team[j])
                        team_max[j] = team_max[u] + team[j];
                }
            }
        }

    }

}


int main(){
    cin >> n >> m >> c1 >> c2;

    for(int i = 0; i < n; i++)
        cin >> team[i];

    fill(city[0], city[0] + MAXN*MAXN, INT_MAX);

    int u, v, len;
    for(int i = 0; i < m; i++){
        cin >> u >> v >> len;
        city[u][v] = city[v][u] = len;
    }

    Dijkstra(c1);
    cout << road[c2] << ' ' << team_max[c2] << endl;


    return 0;
}

(2019.3.19)

#include <iostream>
#include <climits>
using namespace std;

#define MAXN 505

int n, m, c1, c2;   // city road first_city final_city
int team[MAXN], city[MAXN][MAXN];       // 各城市队伍数   路径图
int dis[MAXN], weight[MAXN], num[MAXN]; // 最短距离     救援人数    最短路径条数
bool visit[MAXN];

int main(){
    cin >> n >> m >> c1 >> c2;
    for(int i = 0; i < n; i++)
        cin >> team[i];

    fill(city[0], city[0] + MAXN*MAXN, INT_MAX);
    fill(dis, dis + MAXN, INT_MAX);

    int u, v, len;
    for(int i = 0; i < m; i++){
        cin >> u >> v >> len;
        city[u][v] = city[v][u] = len;
    }

    dis[c1] = 0;
    weight[c1] = team[c1];
    num[c1] = 1;

    for(int i = 0; i < n; i++){
        int start = -1, cur_min = INT_MAX;

        // 找出当前到起点最近的点
        for(int j = 0; j < n; j++)
            if(visit[j] == false && dis[j] < cur_min){
                start = j;
                cur_min = dis[j];
            }

        if(start == -1)
            break;

        visit[start] = 1;
        // 更新其余点到start 的距离
        for(int j = 0; j < n; j++){
            if(visit[j] == false && city[start][j] != INT_MAX){
                if(dis[start] + city[start][j] < dis[j]){
                    dis[j] = dis[start] + city[start][j];
                    num[j] = num[start];
                    weight[j] = weight[start] + team[j];
                }else if(dis[start] + city[start][j] == dis[j]){
                    num[j] += num[start];

                    if(weight[start] + team[j] > weight[j])
                        weight[j] = weight[start] + team[j];
                }
            }
        }

    }

    cout << num[c2] << ' ' << weight[c2] << endl;

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值