代码及注释:
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
#define debug cout<<"debug"<<endl
mt19937 rd(time(0));
typedef long long ll;
typedef long double ld;
typedef pair<int, int> PII;
const double eps = 1e-5;
const double PI = 3.14159265358979323;
const int N = 2e5+10, M = 2*N, mod = 1e9+7;
const int INF = 0x3f3f3f3f;
int n, m;
ll dis[2][N];
struct Node
{
int w, state, to;
};
typedef pair<int, PII> Pii;
vector<Node> v1[N], v2[N];
int vis[2][N];
void add(int a, int b, int c)
{
v1[a].push_back({c, 0, b}); // 正向边
v2[b].push_back({c, 1, a}); // 反向边
}
void dijkstra()
{
memset(dis, 0x3f, sizeof dis);
priority_queue<Pii, vector<Pii>, greater<Pii> > q;
dis[0][1] = 0;
q.push({dis[0][1], {0, 1}});
while(q.size())
{
auto t = q.top(); q.pop();
int ver = t.second.second, st = t.second.first;
if(vis[st][ver]) continue;
vis[st][ver] = 1;
// 中点mid 求min(1到mid的最短路+mid到x的最短), 只能走正向
if(!st) // 正向最短路更新
{
for(int i = 0; i<v1[ver].size(); i++)
{
int j = v1[ver][i].to, w = v1[ver][i].w;
// 只能正着走
if(dis[0][j] > dis[0][ver] + w)
{
dis[0][j] = dis[0][ver] + w;
q.push({dis[0][j], {0, j}});
}
}
}
// 反向图更新
// mid到x可以是正常的1到x中的最短路, 也可以是反向图即x到mid的最短路, 即正反都能走
for(int i = 0; i<v2[ver].size(); i++)
{
int j = v2[ver][i].to, w = v2[ver][i].w;
// 正反都能走
if(dis[1][j] > min(dis[0][ver], dis[1][ver]) + w)
{
dis[1][j] = min(dis[0][ver], dis[1][ver]) + w;
q.push({dis[1][j], {1, j}});
}
}
}
}
void solve()
{
cin>>n>>m;
while(m -- )
{
int a, b, c; cin>>a>>b>>c;
add(a, b, c);
}
dijkstra();
int k; cin>>k;
// 中点mid 求min(1到mid的最短路+mid到x的最短)
// mid到x可以是正常的1到x中的最短路, 也可以是反向图即x到mid的最短路
while(k -- )
{
int x; cin>>x;
// cout<<dis[0][x]<<" "<<dis[1][x]<<endl;
ll ans = min(dis[0][x], dis[1][x]);
if(ans == 0x3f3f3f3f3f3f3f3f) cout<<-1<<endl;
else cout<<ans<<endl;
}
}
int main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int T;
T = 1;
// cin>>T;
while(T -- )
{
solve();
}
return 0;
}