LuoguP1629 邮递员送信 题解
这里先说个题外话——
正如我在此题讨论区里发的一个帖子所说,这个题目和P1342 请柬是一样的,但是需要开大数组,并将答案开\(long~long\)。
好了不多说正式进入题解。
其实楼上的巨佬们都已经讲得很清楚了,就是从1到各个点的最短路和各个点到1的最短路的权值和加起来就行了。
这里给大家安利一下堆优化+\(Dijkstra\)的代码(其实不用加\(int\)其实我是先做了1342再复制粘贴过这题的233):
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#define ll long long
using namespace std;
ll n, m, u, v, w, h1[2000007], h2[2000007], cnt1, cnt2, dis[2000007], vis[2000007];
struct edge {
ll v, to, nxt;
}e1[2000007], e2[2000007];
priority_queue<pair<ll, ll> > q;
inline ll read() {
ll f = 1ll, x = 0ll;
char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
void a_e(ll u, ll v, ll w) {
e1[++cnt1] = (edge){w, v, h1[u]}; h1[u] = cnt1;
e2[++cnt2] = (edge){w, u, h2[v]}; h2[v] = cnt2;
}
ll dj() {
ll ans = 0;
memset(dis, 0x3f, sizeof(dis));
dis[1] = 0;
q.push(make_pair(0ll, 1ll));
while(!q.empty()) {
ll x = q.top().second;
q.pop();
if(vis[x]) continue;
vis[x] = 1;
for(ll i = h1[x]; i; i = e1[i].nxt) {
ll y = e1[i].to, z = e1[i].v;
if(dis[y] > dis[x] + z) {
dis[y] = dis[x] + z;
q.push(make_pair(-dis[y], y));
}
}
}
for(ll i = 2; i <= n; ++i) {
// printf("1 to %d's distance is %d.\n", i, dis[i]);
ans += dis[i];
}
while(!q.empty()) q.pop();
memset(dis, 0x3f, sizeof(dis));
memset(vis, 0, sizeof(vis));
dis[1] = 0;
q.push(make_pair(0ll, 1ll));
while(!q.empty()) {
ll x = q.top().second;
q.pop();
if(vis[x]) continue;
vis[x] = 1;
for(ll i = h2[x]; i; i = e2[i].nxt) {
ll y = e2[i].to, z = e2[i].v;
if(dis[y] > dis[x] + z) {
dis[y] = dis[x] + z;
q.push(make_pair(-dis[y], y));
}
}
}
for(ll i = 2; i <= n; ++i) {
// printf("%d to 1's distance is %d.\n", i, dis[i]);
ans += dis[i];
}
return ans;
}
int main() {
n = read(), m = read();
for(ll i = 1; i <= m; ++i) {
u = read(), v = read(), w = read();
a_e(u, v, w);
}
printf("%lld", dj());
return 0;
}
不先点个赞再走嘛?qwq

浙公网安备 33010602011771号