思路:
改造版的dij,记录每个点的最短路从哪个奇葩点来,然后每次更新答案
c o d e code code
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#define ll long long
using namespace std;
const ll MAXN = 1e5 + 10;
ll n, m, k, dis[MAXN][2];
ll tot, head[MAXN], ans = 1e18;
struct node {
ll to, next, w;
}b[MAXN * 5];
bool v[MAXN];
priority_queue<pair<ll, pair<ll, ll> > > q;
void add(ll x, ll y, ll w) {
b[++ tot] = (node) { y, head[x], w };
head[x] = tot;
}
void dij() {
while(!q.empty()) {
ll len = q.top().first, x = q.top().second.first, fa = q.top().second.second;
q.pop();
if(v[x]) continue;
v[x] = 1;
dis[x][1] = fa;
for(ll i = head[x]; i; i = b[i].next) {
ll y = b[i].to;
if(dis[y][1] != dis[x][1] && dis[y][0] + dis[x][0] + b[i].w < ans) ans = dis[y][0] + dis[x][0] + b[i].w;
if(dis[y][0] > dis[x][0] + b[i].w) {
dis[y][0] = dis[x][0] + b[i].w;
q.push(make_pair(-dis[y][0], make_pair(y, fa)));
}
}
}
}
int main() {
scanf("%lld%lld%lld", &n, &m, &k);
for(ll i = 1; i <= m; i ++) {
ll x, y, w;
scanf("%lld%lld%lld", &x, &y, &w);
add(x, y, w), add(y, x, w);
}
memset(dis, 0x7f, sizeof(dis));
for(ll i = 1; i <= k; i ++) {
ll x;
scanf("%lld", &x);
dis[x][0] = 0;
dis[x][1] = x;
q.push(make_pair(0, make_pair(x, x)));
}
dij();
printf("%lld", ans);
return 0;
}