题意:https://www.luogu.com.cn/problem/AT_abc277_e
思路:首先看到求某点到某点的最短距离,第一个想到的肯定时dij,那么我们考虑如何建图,对于整个图有两种状态时,一定要想到直接把图拓展一倍大小,然后根据切换状态的条件去建边。
/*keep on going and never give up*/
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
#define int long long
typedef pair<int, int> pii;
#define lowbit(x) x&(-x)
#define endl '\n'
#define wk is zqx ta die
int s[200005];
int vis[200005];
int dis[400005];
vector<int> vc[400005];
signed main() {
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, m, k;
cin >> n >> m >> k;
for (int i = 1; i <= 2 * n; i++) {
dis[i] = 1e18;
}
for (int i = 1; i <= m; i++) {
int u, v, c;
cin >> u >> v >> c;
if (c) {
vc[u].push_back(v);
vc[v].push_back(u);
} else {
vc[u + n].push_back(v + n);
vc[v + n].push_back(u + n);
}
}
for (int i = 1; i <= k; i++) {
cin >> s[i];
vc[s[i]].push_back(s[i] + n);
vc[s[i] + n].push_back(s[i]);
}
priority_queue<pii, vector<pii>, greater<pii>> p;
p.push({0, 1});
dis[1] = 0;
while (!p.empty()) {
pii to = p.top();
p.pop();
int u = to.second;
// if (vis[u]) {
// continue;
// }
// vis[u] = 1;
for (auto x : vc[u]) {
if (abs(x - u) != n) {
if (dis[x] > dis[u] + 1) {
dis[x] = dis[u] + 1;
p.push({dis[x], x});
}
} else {
if (dis[x] > dis[u]) {
dis[x] = dis[u];
p.push({dis[x], x});
}
}
}
}
int ans = min(dis[n], dis[2 * n]);
if (ans == 1e18) {
cout << "-1" << endl;
} else {
cout << ans << endl;
}
return 0;
}