7-35 城市间紧急救援 (25 分)

7-35 城市间紧急救援 (25 分)

作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队。

输入格式:

输入第一行给出4个正整数$N$、$M$、$S$、$D$,其中$N$(2≤$N$≤500)是城市的个数,顺便假设城市的编号为0 ~ ($N$−1);$M$是快速道路的条数;$S$是出发地的城市编号;$D$是目的地的城市编号。

第二行给出$N$个正整数,其中第$i$个数是第$i$个城市的救援队的数目,数字间以空格分隔。随后的$M$行中,每行给出一条快速道路的信息,分别是:城市1、城市2、快速道路的长度,中间用空格分开,数字均为整数且不超过500。输入保证救援可行且最优解唯一。

输出格式:

第一行输出最短路径的条数和能够召集的最多的救援队数量。第二行输出从$S$到$D$的路径中经过的城市编号。数字间以空格分隔,输出结尾不能有多余空格。

输入样例:

1
2
3
4
5
6
7
4 5 0 3
20 30 40 10
0 1 1
1 3 2
0 3 3
0 2 2
2 3 2

输出样例:

1
2
2 60
0 1 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117

#include<iostream>
#include<queue>
#include<vector>
#include<set>

using namespace std;

struct node {
int v, len;
node(int _v, int _len) {
v = _v;
len = _len;
}
};

int N, M, S, D, INF = 1000000000;
int teams[500], d[500], countInq[500];
vector<node> graph[500];
bool inq[500];
set<int> pre[500];
vector<int> tempPath, path;
int count = 0, maxTeams = 0;

bool spfa(int s);
void dfs(int nowVisit);

int main() {
std::ios::sync_with_stdio(false);
cin >> N >> M >> S >> D;
for(int i = 0; i < N; i++) {
cin >> teams[i];
}
for(int i = 0; i < M; i++) {
int v1, v2, len;
cin >> v1 >> v2 >> len;
graph[v1].push_back(node(v2, len));
graph[v2].push_back(node(v1, len));
}
spfa(S);
dfs(D);
cout << count << " " << maxTeams << endl;
for(int i = path.size() - 1; i >= 0; i--){
cout << path[i];
if(i == 0){
cout << endl;
}else{
cout << " ";
}
}
return 0;
}

bool spfa(int s) {
fill(d, d + N, INF);
fill(countInq, countInq + N, 0);
fill(inq, inq + N, false);
d[s] = 0;
queue<int> q;
q.push(s);
countInq[s]++;
inq[s] = true;
while(!q.empty()) {
int u = q.front();
q.pop();
inq[u] = false;
for(int i = 0; i < graph[u].size(); i++) {
int v = graph[u][i].v;
int len = graph[u][i].len;
if(d[u] + len < d[v]) {
d[v] = d[u] + len;
pre[v].clear();
pre[v].insert(u);
if(!inq[v]) {
q.push(v);
inq[v] = true;
countInq[v]++;
if(countInq[v] > N - 1){
return false;
}
}
}else if(d[u] + len == d[v]) {
pre[v].insert(u);
if(!inq[v]) {
q.push(v);
inq[v] = true;
countInq[v]++;
if(countInq[v] > N - 1){
return false;
}
}
}
}
}
return true;
}

void dfs(int nowVisit) {
tempPath.push_back(nowVisit);
if(nowVisit == S){
count++;
int tempTeams = 0;
for(int i = 0; i < tempPath.size(); i++){
tempTeams += teams[tempPath[i]];
}
if(tempTeams > maxTeams){
maxTeams = tempTeams;
path = tempPath;
}
tempPath.pop_back();
return;
}
for(set<int>::iterator it = pre[nowVisit].begin(); it != pre[nowVisit].end(); it++){
dfs(*it);
}
tempPath.pop_back();
}
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×