杭電OJ 2066 一個人的旅行

paopaotangzu發表於2024-03-19

一個人的旅行

考查圖論中的單源最短路徑問題,首先圖的儲存方式,前面說過在實際程式中一般用鄰接表,為每一個頂點都分配一個單連結串列(向量)。由於這裡頂點的總個數並不確定,用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.

相關文章