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