#sicily#1003.campus

本文介绍了一种解决中山大学不同校区间最短路径问题的方法。采用Floyd算法实现,能够快速找到任意两点间的最短距离。文章提供了完整的源代码及注意事项。

source:http://soj.sysu.edu.cn/show_problem.php?pid=1003&cid=2388

闲话

大tai家ga好hau,我又ngai来-iu填ten坑hang咯lo。

问题不难理解,就是求两点间最短路径长度。但是有一些坑点需要注意。
1.多个测例是指多次输入数据,每次都求一次最短路径。因此每一次测例都要更新地图。
2.请求的路径两端地点有可能不全在地图上,这是就要判断是。如果有不在的,输出-1;
3.坑上坑来了!!!!在2的基础上,不管一个地点是否已经在地图上,如果起点、终点都是同一个地点,都输出0.但是很可能此种情况在2的情况就输出了-1,而我们不知道错在哪里?

填得坑上坑,方为程序员……吗?[捂脸]

题目

Time Limit: 1sec Memory Limit:32MB

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

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

Copy sample input to clipboard
1
2
South.xiaolitang South.xiongdelong 2
South.xiongdelong Zhuhai.liyuan 100
South.xiongdelong South.xiaolitang
Sample Output
2
Problem Source: ZSUACM Team Member

算法思想

我这里用的是floyd算法,主要优点是容易写,并且一次可以求出任意两个节点的最短距离,而不需要指定起点终点。
算法的核心代码如下:

// search
        for (int k = 1; k < idCounter; k++) {
            for (int i = 1; i < idCounter; i++) {
                for (int j = 1; j < idCounter; j++) {
                    adjMat[i][j] = min(adjMat[i][j], adjMat[i][k] + adjMat[k][j]);
                }
            }
        }

注意使用前要把adtMat[i][j]置为(i==j?)0:INF,然后读入地图数据。
这个算法简洁得优美。就像优化并查集一样漂亮!

源代码

#include <map>
#include <string>
#include <algorithm>

#define INF 10001

using namespace std;
int adjMat[210][210];
int idCounter;

int main() {
    int c, n, id1, id2;
    string str1, str2;
    cin >> c;
    while(c--) {
        map<string, int> myMap;
        idCounter = 1;
        //initialize adjacent matrix
        for (int i = 1; i <= 205; i++) {
            for (int j = 1; j <= 205; j++) {
                if (i != j) {
                    adjMat[i][j] = adjMat[j][i]= INF;
                } else {
                    adjMat[i][j] = 0;
                }
            }
        }
        cin  >> n;
        for (int i = 0; i < n; i++) {
            cin >> str1 >> str2;
            if (0 == myMap.count(str1)) {myMap[str1] = idCounter; idCounter++;}
            id1 = myMap[str1];
            if (0 == myMap.count(str2)) {myMap[str2] = idCounter; idCounter++;}
            id2 = myMap[str2];
            cin >> adjMat[id1][id2];
            adjMat[id2][id1] = adjMat[id1][id2];
        }

        // search
        for (int k = 1; k < idCounter; k++) {
            for (int i = 1; i < idCounter; i++) {
                for (int j = 1; j < idCounter; j++) {
                    adjMat[i][j] = min(adjMat[i][j], adjMat[i][k] + adjMat[k][j]);
                }
            }
        }

        cin >> str1 >> str2;
        if (str1 == str2) {
            cout << 0 << endl;
        } else if (0 == myMap.count(str1) || 0 == myMap.count(str2)) {
            cout << "-1" << endl;
        } else if (adjMat[myMap[str1]][myMap[str2]] == INF) {
            cout << "-1" << endl;
        } else {
            cout << adjMat[myMap[str1]][myMap[str2]] << endl;
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值