1003. Emergency (25)

题目链接:https://www.patest.cn/contests/pat-a-practise/1003

题意:n个城市构成一个地图,某些城市之间有使之相连的道路,每个城市都有一定的救援队,问从指定的城市到达另一个城市最短路径的数量以及其中能够拥有的最多救援队数量

分析:dfs,注意一个坑:出发地和目的地可能是同一城市

//写的太慢啦。。。
//dfs
#include <iostream>
#include <vector>
#include <climits> //INT_MAX
using namespace std;
const int N = 505;

struct node {
    int city;
    int rescue_team;
};
struct graph {
    vector<node> c[N];
    int len[N][N];
};

int n, m, s, e;
int short_path_len = INT_MAX; //宏
int short_path_num, max_rescue_team;
graph g;
node v[N];
bool vis[N][N];

void Read() {
    cin >> n >> m >> s >> e;
    int rescue_team;
    for (int i = 0; i < n; i++) {
        v[i].city = i;
        cin >> rescue_team;
        v[i].rescue_team = rescue_team;
    }
    int city1, city2, len;
    for (int i = 0; i < m; i++) {
        cin >> city1 >> city2 >> len;
        //添加'链表'结点
        g.c[city1].push_back(v[city2]); 
        g.c[city2].push_back(v[city1]);
        g.len[city1][city2] = g.len[city2][city1] = len;
    }
}

void DFS(int city1, int city2, int rescue_team, int path_len) {
    rescue_team += v[city2].rescue_team;
    path_len += g.len[city1][city2];
    if (city2 == e) {
        //以s->e路径长度为基准进行更新
        if (path_len < short_path_len) {
            short_path_len = path_len;
            max_rescue_team = rescue_team;
            short_path_num = 1;
        }
        else if (path_len == short_path_len) {
            if (rescue_team > max_rescue_team) max_rescue_team = rescue_team;
            short_path_num++;
        }
        return;
    }
    for (vector<node>::iterator it = g.c[city2].begin(); it != g.c[city2].end(); it++) {
        if (!vis[city2][it->city]) {
            vis[city2][it->city] = vis[it->city][city2] = true; 
            DFS(city2, it->city, rescue_team, path_len);
            vis[city2][it->city] = vis[it->city][city2] = false; 
        }
    }
}

void Solve() {
    //s、e为不同城市
    if (s != e) {
        for (vector<node>::iterator it = g.c[s].begin(); it != g.c[s].end(); it++) {
            if (!vis[s][it->city]) {
                vis[s][it->city] = vis[it->city][s] = true; //对称置true, 放在DFS函数前
                DFS(s, it->city, v[s].rescue_team, 0);
                vis[s][it->city] = vis[it->city][s] = false; //回溯时取消标记
            }
        }
    }
    else short_path_num = 1, max_rescue_team = v[s].rescue_team;
}
int main() {
    Read();
    Solve();
    cout << short_path_num << " " << max_rescue_team << '\n';
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值