小红送外卖 | Dijkstra性质
小红送外卖
https://www.nowcoder.com/practice/2850d7c941f6494e82ba74bc899eb512
题意
小红在第三新北林市的学园城送外卖,学园城中有非常多的学校,学园城里有一个美食街。小红每次会接一些同一个学校的订单,然后从美食街取餐出发,再骑车将外卖送到学校,最后回到美食街,以此往复。
学园城有 n 个结点, m 条道路,美食街为1号结点,剩下的结点都是学校,保证学园城中所有结点连通。给出小红每次要送外卖的学校,请计算小红最少需要骑行的距离。
思路
考察Dijkstra算法的性质
当Dijkstra算法完成后,源点到所有已访问顶点的距离是最短的。然而,对于未访问的顶点,算法不能保证它们到源点的距离是最短的,因为算法一旦一个顶点被确定为已访问,就不会再考虑它。题目说 保证所有结点都是联通的,所以跑完Dijkstra以后,从1出发到达所有结点的距离都是最短的,累加dis[x]*2就是答案
乘以2是因为来回的距离
注意用long long
Cpp代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e6 + 10;
typedef pair<long long, long long> PII;
int n, m, q;
int h[maxn], w[maxn], e[maxn], ne[maxn], idx;
long long dis[maxn];
bool st[maxn];
void add(int a, int b, int c) {
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}
void dijkstra() {
for (int i = 0; i <= n + 3; i++) {
dis[i] = 1e18;
st[i] = false;
}
dis[1] = 0;
///建立一个维护最小值的优先队列
priority_queue<PII, vector<PII>, greater<PII>>heap;
heap.push({0, 1}); ///起始点放入队列
while (heap.size()) {
auto t = heap.top(); ///最小值
heap.pop();
long long ver = t.second, dd = t.first;
if (st[ver]) continue; ///该点更新
st[ver] = true;
for (int i = h[ver]; i != -1; i = ne[i]) {
int j = e[i];
if (dis[j] > dd + w[i]) {
dis[j] = dd + w[i];
heap.push({dis[j], j});
}
}
}
}
int main() {
cin >> n >> m >> q;
memset(h, -1, sizeof h);
for (int i = 1; i <= m; i++) {
int u, v, w;
cin >> u >> v >> w;
add(u, v, w);
add(v, u, w);
}
dijkstra();
long long res = 0;
while(q--){
int x;cin>>x;
res += dis[x]*2;
}
cout<<res<<endl;
return 0;
}
#牛客创作赏金赛#15天大厂真题带刷Go题解 文章被收录于专栏
15天大厂真题带刷Golang题解
深信服公司福利 732人发布
