pat-1003 Emergency
一、原题
几个城市,每个城市有一定数量的救援队,输出最短路径的条数,输出在最短的几条路径中,能集结到的最多的救援队数量。
二、思路
使用深度优先遍历。
代码中N,M,C1,C2为原题目中的变量,N-城市数量,M-路的数量,C1-起点,C2-终点
roads-使用二维数组来记录路径长度,teams-记录每个城市的救援队数量
dfs(当前的城市,当前路径的长度,当前累积的救援队数量)
在示例中
-
访问0号城市,发现和0号城市相连、没有走过的城市有1、2、3号
-
访问1号城市,发现和1号城市相连、没有走过的城市有2号
-
访问2号城市,到终点,更新全局变量,结束当前层,退回到1号(第二条)
-
第二条中,和1号城市相连、没有走过的城市 没有了,结束当前层,退回到0号(第一条)
-
第一条中,和0号城市相连、没有走过的城市还有2、3号(for循环保证了不会再走一遍1号)
-
访问2号城市,到终点,更新全局变量,结束当前层,退回到0号(第一条)
-
第一条中,和0号城市相连、没有走过的城市还有3号(for循环保证了不会再走一遍1、2号)
-
访问3号城市,和3号城市相连、没有走过的城市有4号
-
访问4号城市,和4号城市相连、没有走过的城市有2号
-
访问2号城市,到终点,更新全局变量,结束当前层,退回到4号(第九条)
-
第九条中,和4号城市相连、没有走过的城市 没有了,结束当前层,退回到3号(第八条)
-
第八条中,和3号城市相连、没有走过的城市 没有了,结束当前层,退回到0号(第一条)
-
第一条中,和0号城市相连、没有走过的城市 没有了,结束当前层,全部结束
示例遍历顺序:
dfs(0,0,1)->dfs(1,1,3)->dfs(2,2,4)
dfs(2,2,2)
dfs(3,1,6)->dfs(4,2,9)->dfs(2,3,10)
三、代码
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 510
#define INF 1e9
int N, M, C1, C2;
int roads[MAXN][MAXN] = { 0 };
int teams[MAXN];
int dist=1e9;//最短路径长度
int teamsAccumulated;//积累的团队数量
int roadsNumber;//最短路径数量
int visited[MAXN];//用于控制当前路径不走重复的路
void dfs(int currentCity,int currentDist,int currentTeamsAccumulated){
if (currentCity == C2){//到达终点
if (currentDist < dist){//新的最短路径
dist = currentDist;
roadsNumber = 1;
teamsAccumulated = currentTeamsAccumulated;
}
else if (currentDist == dist){//新增一条最短路径
roadsNumber++;
teamsAccumulated = currentTeamsAccumulated > teamsAccumulated ? currentTeamsAccumulated : teamsAccumulated;
}
}
for (int i = 0; i < N; i++){
if (i != currentCity&&roads[currentCity][i] && !visited[i]){
visited[i] = 1;
dfs(i, currentDist + roads[currentCity][i], currentTeamsAccumulated + teams[i]);
visited[i] = 0;
}
}
}
int main(){
cin >> N >> M >> C1 >> C2;
int tempc1, tempc2, templength;
for (int i = 0; i < N; i++){
cin >> teams[i];
}
for (int i = 0; i < M; i++){
cin >> tempc1 >> tempc2 >> templength;
roads[tempc1][tempc2] += templength;
roads[tempc2][tempc1] += templength;
}
visited[C1] = 1;
dfs(C1, 0, teams[C1]);
cout << roadsNumber << " " << teamsAccumulated << endl;
return 0;
}
四、结果与总结
在dfs的代码里面,其实可以在路径长度超过当前已保存的最短路径就返回,这样剪枝效率应该会高一些,但是已经过了,就没有再改了