Sicily 1031. Campus 解题报告

1031_Campus

题目链接:

http://soj.me/1031

题目大意:

给出四个校区的一些地点之间的距离,地点名用字符串来表示,问某两个地点之间的最短路径长度,典型的单源最短路径题目

思路:

单源最短路径问题可以用dijkstra算法实现,这道题比较麻烦的是用字符串来表示地点,我用的处理方法是建立map得到地点名字到序号的映射,对于每个新输入的地点名字,先在map里面查找是否存在,如果不存在就绑定一个新的序号.地点之间的距离用邻接矩阵来存放.

代码:

#include <iostream>
#include <memory.h>
#include <map>
#include <queue>
#include <vector>
using namespace std;

const int INF = 100000;
int distances[300][300];
int shortest[300];
bool included[301];
map<string, int> m;
int numRoads;
int numPlaces;
string start_name, end_name;

void input_and_init();
int find_shortest();
int find_nearest();

int main() {
    int numTestcases;
    cin >> numTestcases;
    while (numTestcases--) {
        input_and_init();

        if(start_name == end_name)
            cout << 0 << endl;
        else if(m.count(start_name) == 0 || m.count(end_name) == 0)
            cout << -1 << endl;
        else
            cout << find_shortest() << endl;
    }
    return 0;
}
void input_and_init(){
    cin >> numRoads;
    numPlaces = 0;
    m.clear();
    for (int i = 0; i < 300; ++i) {
        for (int j = 0; j < 300; ++j) {
            distances[i][j] = (i == j ? 0 : INF);
        }
    }
    memset(included, false, sizeof(included));
    for (int i = 0; i < 300; ++i) {
        shortest[i] = INF;
    }

    string s1, s2;
    int d;
    for (int i = 0; i < numRoads; ++i) {
        cin >> s1 >> s2 >> d;
        if(m.count(s1) == 0)
            m[s1] = ++numPlaces;
        if(m.count(s2) == 0)
            m[s2] = ++numPlaces;
        distances[m[s1]][m[s2]] = distances[m[s2]][m[s1]] = d;
    }
    cin >> start_name >> end_name;
}

int find_shortest(){
    //Post: 如果起点和终点间有连通则返回最短路径长度,否则返回-1
    int start = m[start_name], end = m[end_name];
    shortest[start] = 0;
    for (int i = 0; i < numPlaces; ++i) {
        int cur = find_nearest();
        included[cur] = true;
        for (int j = 1; j <= numPlaces; ++j) {
            if(!included[j]  && shortest[j] > shortest[cur] + distances[cur][j]){
                shortest[j] = shortest[cur] + distances[cur][j];
            }
        }
    }
    if(shortest[end] < INF)
        return shortest[end];
    else
        return -1;
}
int find_nearest(){
    //返回当前离集合S最近的点的下标
    int nearest_index = 0;
    int shortestDistance = INF;
    for (int i = 1; i <= numPlaces; ++i) {
        if(shortest[i] < shortestDistance && !included[i]){
            nearest_index = i;
            shortestDistance = shortest[i];
        }
    }
    return  nearest_index;
}
时间: 2024-10-14 20:19:24

Sicily 1031. Campus 解题报告的相关文章

Sicily 1090. Highways 解题报告

题目链接:Sicily 1090 思路: 简单的最小生成树问题,这里用prim算法即可.用visited数组记录每个结点是否已经被访问,即是否已经在最小生成树中.每次从不在最小生成树中的结点中取出一个key值最小的结点放入生成树中,key值表示结点到已经在生成树中点集合的最小距离.每次加入一个结点后更新与它相邻的结点的key值. 代码: #include <iostream> #include <queue> #include <stdio.h> #include &l

sicily 1031 Campus(图算法)

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 kilo

Sicily 1321. Robot 解题报告

1321_Robot 题目链接: http://soj.me/1321 题目大意: 给一个矩阵,每一个点上面的数字表示走到该点需要的花费,找出给定起点到终点的最小总花费 思路: 每个格子看作一个结点,花费可以看作从上一个点走到这个点的路程,那么这道题就是典型的最短路径问题,可以用Dijkstra算法解决.一开始直接套用整个算法,将每个新的结点加入到集合S中的时候,更新所有不在集合中的结点的最短路径并排序以便下一次找出路径最短的结点,结果超时. 这里使用了优先队列q来优化,q里面放入每次可以加入到

Sicily 1308. Dependencies among J 解题报告

题目:1308. Dependencies among J 思路: 比较简单的一道题,要知道m最早完成的时间,只需要找出所有需要在m之前完成的工作,将它们的完成时间加起来即可.这里使用vector的数组存储每个结点的邻接点,从结点m开始,依次宽度优先搜索m的每个邻接点...数组visited记录每个结点是否被访问过,遇到已经访问过的结点直接跳过. 读取的时候一开始没有找到解决办法,要读取一行的数字,并且要判断是否换行,可以首先读取第一个数即完成时间,然后用getchar读取一个字符,如果是'\n

Sicily 1350. Piggy banks 解题报告

题目:1350. Piggy banks 思路: 首先把每个钥匙的位置存进key_positions[]中,然后从第一个bank开始,用不同的color给它们分组.比如第一个bank的钥匙在第二个bank中,那么可以直接先开第二个,第二个钥匙在第四个bank中,同样可以先开第四个,以此类推,直到某个钥匙出现在前面的同一组的某个bank中则需要打破一个.visited数组初始化为0,然后访问过后标记为颜色的编号.第21行visited[cur] == color只有找到颜色相同即在同一组的才需要打

解题报告 之 POJ3057 Evacuation

解题报告 之 POJ3057 Evacuation Description Fires can be disastrous, especially when a fire breaks out in a room that is completely filled with people. Rooms usually have a couple of exits and emergency exits, but with everyone rushing out at the same time

hdu 1541 Stars 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1541 题目意思:有 N 颗星星,每颗星星都有各自的等级.给出每颗星星的坐标(x, y),它的等级由所有比它低层(或者同层)的或者在它左手边的星星数决定.计算出每个等级(0 ~ n-1)的星星各有多少颗. 我只能说,题目换了一下就不会变通了,泪~~~~ 星星的分布是不是很像树状数组呢~~~没错,就是树状数组题来滴! 按照题目输入,当前星星与后面的星星没有关系.所以只要把 x 之前的横坐标加起来就可以了

【百度之星2014~初赛(第二轮)解题报告】Chess

声明 笔者最近意外的发现 笔者的个人网站http://tiankonguse.com/ 的很多文章被其它网站转载,但是转载时未声明文章来源或参考自 http://tiankonguse.com/ 网站,因此,笔者添加此条声明. 郑重声明:这篇记录<[百度之星2014~初赛(第二轮)解题报告]Chess>转载自 http://tiankonguse.com/ 的这条记录:http://tiankonguse.com/record/record.php?id=667 前言 最近要毕业了,有半年没做

2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告

2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告 勘误1:第6题第4个 if最后一个条件粗心写错了,答案应为1580. 条件应为abs(a[3]-a[7])!=1,宝宝心理苦啊.!感谢zzh童鞋的提醒. 勘误2:第7题在推断连通的时候条件写错了,后两个if条件中是应该是<=12 落了一个等于号.正确答案应为116. 1.煤球数目 有一堆煤球.堆成三角棱锥形.详细: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形), 第四层10个(排列成三角形). -. 假设一共