Sicily 1031. Campus

本文详细介绍Dijkstra算法的应用及实现过程,使用STL容器优化代码结构,通过实例讲解如何解决单源最短路径问题。文章涉及节点存储、邻接矩阵表示、优先队列应用等内容。

单源最短路(Dijkstra)。有以下几点需要注意:

1、用STL容器map来保存所有的结点(0~n)。

2、当询问的地点在map中没有出现过时,要分两种情况考虑:(1)两个地点一样,输出0(LZ在这里被坑了多次WA);(2)两个地点不同,只要有一个没出现过就输出-1。

3、保存结点与边的关系可以用邻接表或者矩阵都行,本文用的是矩阵(个人觉得比较方便,但是如果是稀疏图空间复杂度会高些)。

4、Dijkstra算法实现过程再次用到STL容器——priority_queue。

5、建了一个Node结构体,并重载"<"运算符,实现队列的排序方式。

// Problem#: 1031
// Submission#: 2199903
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <iostream>
#include <vector>
#include <string.h>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <queue>
#include <map>
#include <string>
#include <stack>
using namespace std;

const int inf = 0x3f3f3f3f;
struct Node{
    int ve, dist;
    Node(){}
    Node(int v, int d): ve(v), dist(d){}
    bool operator < (const Node &n) const{
        return dist > n.dist;
    }
};

int Dijkstra(int src, int dst, int n, vector<vector<int> > mat){
    priority_queue<Node> q;
    q.push(Node(src, 0));
    vector<int> dist(n, inf);
    vector<bool> vis(n, 0);
    dist[src] = 0;
    Node top;
    while(!q.empty() && q.top().ve != dst){
        top = q.top();
        q.pop();
        vis[top.ve] = true;
        for(int i = 0; i < n; i++){
            if(!vis[i] && mat[top.ve][i] != -1 && dist[top.ve] + mat[top.ve][i] < dist[i]){
                dist[i] = dist[top.ve] + mat[top.ve][i];
                q.push(Node(i, dist[i]));
            }
        }
    }
    return dist[dst];
}
int main(){
    int t;
    //freopen("in.txt", "r", stdin);
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        map<string, int> pnt;
        string s1, s2;
        int val;
        int cnt = 0;
        //int mat[205][205];
        vector<vector<int> > mat(205, vector<int>(205, -1));
        for(int i = 0; i < n; i++){
            cin >> s1 >> s2 >> val;
            if(pnt.find(s1) == pnt.end())
                pnt[s1] = cnt++;
            if(pnt.find(s2) == pnt.end())
                pnt[s2] = cnt++;
            mat[pnt[s1]][pnt[s2]] = val;
            mat[pnt[s2]][pnt[s1]] = val;
        }
        cin >> s1 >> s2;
        if(s1 == s2){
            cout << 0 <<endl;
            continue;
        }
        if(pnt.find(s1) == pnt.end() || pnt.find(s2) == pnt.end()){
            cout << -1 <<endl;
            continue;
        }
        int res = Dijkstra(pnt[s1], pnt[s2], cnt, mat);
        if(res < inf)
            cout << res <<endl;
        else cout << -1 <<endl;
    }
}                                 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值