杭电OJ 2066 一个人的旅行

一个人的旅行

考查图论中的单源最短路径问题,首先图的存储方式,前面说过在实际程序中一般用邻接表,为每一个顶点都分配一个单链表(向量)。由于这里顶点的总个数并不确定,用visit数组在集合T中遍历寻找下一个用来松弛的顶点,这一方式不太合适,所以这里我用优先队列,每次弹出距离起始点距离最短的顶点。

//单源最短路径-用优先队列优化每次选择距离起始顶点最短的顶点 2024-03-18 go on
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>

using namespace std;
const int MAXN = 1000 + 10;
const int INF = INT_MAX;
struct Edge {
    int to;
    int time;
    Edge(int t, int ti):to(t), time(ti) {}
};

struct Point {
    int index;
    int distance;
    Point(int i, int d): index(i), distance(d) {}
    bool operator< (const Point &c) const {
        return distance > c.distance;
    }
};

vector<Edge> graph[MAXN];
priority_queue<Point> myPriorityQueue;

int dis[MAXN]; //保存起始点到其他顶点的最短路径

//参数1:起始顶点编号
void Dijkstra(int start) {
    fill(dis, dis + MAXN, INF);
    dis[start] = 0;
    myPriorityQueue.push(Point(start, dis[start]));
    while(!myPriorityQueue.empty()) {
        int u = myPriorityQueue.top().index;
        myPriorityQueue.pop();

        for(int i = 0; i < graph[u].size(); ++i) {
            int v = graph[u][i].to;
            int d = graph[u][i].time;
            if(dis[v] > dis[u] + d) {
                dis[v] = dis[u] + d;
                myPriorityQueue.push(Point(v, dis[v]));
            }
        }
    }
}


int main() {
    int t, s, d;
    vector<int> nearby, want2go;
    while(cin >> t >> s >> d) {
        for(int i = 0; i < t; ++i) {
            int a, b, time;
            scanf("%d%d%d", &a, &b, &time);
            graph[a].push_back(Edge(b, time));
            graph[b].push_back(Edge(a, time));
        }
        int num;
        for(int i = 0; i < s; ++i) {
            scanf("%d", &num);
            nearby.push_back(num);
        }
        for(int i = 0; i < d; ++i) {
            scanf("%d", &num);
            want2go.push_back(num);
        }
        int minimum = INF;
        for(int i = 0; i < s; ++i) {
            Dijkstra(nearby[i]);
            for(int j = 0; j < d; ++j) {
                minimum = min(minimum, dis[want2go[j]]);
            }
        }
        cout << minimum << endl;
        memset(graph, 0, sizeof(graph));
        nearby.clear();
        want2go.clear();
    }
    return 0;
}

All in is a kind of wisdom.

posted @ 2024-03-19 13:15  paopaotangzu  阅读(7)  评论(0编辑  收藏  举报