题目
正确代码
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
#define x first
#define y second
const int N = 1e5+10, M = 3e5+10;
int h[N], e[M], ne[M], w[M], idx;
bool st[N];
int n, m, k, q;
int dist[N];
void add(int a, int b, int c)
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}
void Dijkstra(int i)
{
memset(dist, 0x3f, sizeof dist);
dist[i] = 0;
priority_queue<PII, vector<PII>, greater<PII>> heap;
heap.push({0, i});
while(heap.size())
{
auto t = heap.top(); heap.pop();
int u = t.y, distance = t.x;
if(st[u]) continue;
st[u] = true;
for(int k = h[u]; ~k; k = ne[k])
{
int j = e[k];
if(dist[j] > distance + w[k])
{
dist[j] = distance + w[k];
heap.push({dist[j], j});
}
}
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
memset(h, -1, sizeof h);
for(int i = 1; i <= m; i++)
{
int a, b, c;
cin >> a >> b >> c;
add(a, b, c);
add(b, a, c);
}
cin >> k;
int source = 1e5+1;
while(k--)
{
int num;
cin >> num;
add(source, num, 0);
}
Dijkstra(source);
cin >> q;
while(q--)
{
int num;
cin >> num;
cout << dist[num] << '\n';
}
return 0;
}
感想
用一个虚拟节点把多个目标用长度为0的边一一串起来,最后只要以这个作为source进行Dijkstra就可以计算任意点到目标的最近距离了。
假设边的信息有M条,有向边开M,无向边开2M,加虚拟节点要加边。