Description
At present, Zhongshan University has 4 campuses with a total area of 6.17 square kilometers sitting respectively on both sides of the Pearl River or facing the South China Sea. The Guangzhou South Campus covers an area of 1.17 square kilometers, the North Campus covers an area of 0.39 square kilometers, the Guangzhou East Campus has an area of 1.13 square kilometers and the Zhuhai Campus covers an area of 3.48 square kilometers. All campuses have exuberance of green trees, abundance of lawns and beautiful sceneries, and are ideal for molding the temperaments, studying and doing research.Sometime, the professors and students have to go from one place to another place in one campus or between campuses. They want to find the shortest path between their source place S and target place T. Can you help them?
Input
The first line of the input is a positive integer C. C is the number of test cases followed. In each test case, the first line is a positive integer N=(0<N<=100)
that represents the number of roads. After that, N lines follow. The i-th(1<=i<=N)
line contains two strings Si, Ti and one integer Di(0<=Di<=100)
. It means that there is a road whose length is Di between Si and Ti. Finally, there are two strings S and T, you have to find the shortest path between S and T. S, T, Si(1<=i<=N)
and Ti(1<=i<=N)
are all given in the following format:str_Campus.str_
Place.str_Campus
represents the name of the campus, andstr_Place
represents the place instr_Campus
.str_Campus
is"North"
,"South"
,"East"
or"Zhuhai"
.str_Place
is a string which has less than one hundred lowercase characters from “a-z”. You can assume that there is at most one road directly between any two places.Output
The output of the program should consist of C lines, one line for each test case. For each test case, the output is a single line containing one integer. If there is a path between S and T, output the length of the shortest path between them. Otherwise just output “-1” (without quotation mark). No redundant spaces are needed.Sample Input
1
2
South.xiaolitang South.xiongdelong 2
South.xiongdelong Zhuhai.liyuan 100
South.xiongdelong South.xiaolitangSample Output
2
求图的最短路径主要有两种方法:Dijkstra算法和Floyd算法。对于本题,我采用的是Floyd算法。
对于地图本身,我是用一个data数组来存取图结点的名字,也就是地点的名字,在用一个Graph数组来存取边的权值。
由于此题没有直接输入结点的值,故我们需要从关系的输入中提取。
对于Graph的初始化,根据题目意思和Floyd算法的需要,我们将对角线上的值初始化为0,其他初始化为无穷大。这里的无穷大最好不要设置成0x7fffffff,因为算法中涉及到权重的相加,两个0x7fffffff相加会超出int范围,可能会出错,因此我把无穷大定义为0xfffffff(毕竟对于中大,应该不会出现这么大的权重)。
对于Floyd算法,我推荐:坐在马桶上看算法:只有五行的Floyd最短路算法
只要三重循环就可以实现这个算法,非常简便,这也是我此题选择这个算法的原因。
这道题有几个坑:
1.当查询的地点是不存在且不相同时,输出-1;
2.当查询的地点不存在且相同时,输出0;
3.当查询的地点存在且相同时,输出为0.
即是:
1.不存在且不相同,输出为-1;
2.相同输出为0.
下面是我的代码:
# include <iostream>
# include <string>
# include <queue>
# define MAX 202
using namespace std;
string data[MAX]; // 存取结点数据
int Graph[MAX][MAX]; // 存取图的各边权值
int N; // 结点的数目
void Initialize() {
N = 0;
for (int i = 0; i < MAX; i++) {
data[i] = "";
for (int j = 0; j < MAX; j++) {
if (i == j) {
Graph[i][j] = 0; // 自己到自己路途为0
} else { // 其他情况初始为无穷大
Graph[i][j] = 0xfffffff; // 不能初始化到0x7fffffff,因为涉及到权值相加,可能会超出int的范围
}
}
}
}
int find_index(string str) {
for (int i = 0; i < N; i++) {
if (data[i] == str) {
return i;
}
}
return -1;
}
void Floyd() {
for (int k = 0; k < N; k++) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (Graph[i][j] > Graph[i][k] + Graph[k][j]) {
Graph[i][j] = Graph[i][k] + Graph[k][j];
}
}
}
}
}
int min_lenth(string str1, string str2) {
Floyd();
if (Graph[find_index(str1)][find_index(str2)] == 0xfffffff) {
return -1;
}
return Graph[find_index(str1)][find_index(str2)];
}
int main(void) {
int T;
cin >> T;
while(T--) {
Initialize();
int case_num;
cin >> case_num;
for (int i = 0; i < case_num; i++) {
string str1, str2;
int len;
cin >> str1 >> str2 >> len;
int str1_index, str2_index;
str1_index = find_index(str1);
str2_index = find_index(str2);
if (str1_index == -1) {
data[N++] = str1;
str1_index = N-1;
}
if (str2_index == -1) {
data[N++] = str2;
str2_index = N-1;
}
Graph[str1_index][str2_index] = Graph[str2_index][str1_index] = len;
}
string str1, str2;
cin >> str1 >> str2;
if (find_index(str1) == -1 || find_index(str2) == -1) {
if (str1 == str2) {
cout << "0" << endl;
} else {
cout << "-1" << endl;
}
} else {
cout << min_lenth(str1, str2) << endl;
}
}
return 0;
}
以上内容皆为本人观点,欢迎大家提出批评和指导,我们一起探讨!