题目链接: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;
}