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