LuoguP2384 最短路 题解
堆优化+\(Dijkstra\)居然跑过去了?
其实和普通的最短路没什么两样,就是把dis[y]=dis[x]+z变成dis[y]=(dis[x]*z+mod)%mod就行了。
但你会发现交上去只有\(\color{LimeGreen} \text{90}\)分。
为什么?
仔细看题:
所求路径的边权之积!!!
有可能某条路径刚好是\(9987\)(模数),然后你的最小乘积路径就死打不动地变成\(0\)了!
所以,需要将\(mod\)出\(0\)的某个\(dis\)变成\(1\),就像这样:dis[y] = max((dis[x] * z + mod) % mod, 1ll);
然后毫无压力地跑过去了,\(45ms\)左右的时间。可以说加强数据好像没什么用吗
上\(AC\)代码:
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
const long long mod = 9987;
long long n, m, u, v, w, dis[1007], vis[1007], h[1000007], cnt;
priority_queue<pair<long long, long long> > q;
struct edge {
long long v, to, nxt;
}e[1000007];
inline void a_e(long long u, long long v, long long w) {
e[++cnt] = (edge){w, v, h[u]}; h[u] = cnt;
// e[++cnt] = (edge){w, u, h[v]}; h[v] = cnt;
}
inline void dj() {
for(long long i = 1; i <= n; ++i) dis[i] = (long long)(pow(2, 31) - 1);
dis[1] = 1;
q.push(make_pair(0, 1));
while(!q.empty()) {
long long x = q.top().second;
q.pop();
if(vis[x]) continue;
vis[x] = 1;
for(long long i = h[x]; i; i = e[i].nxt) {
long long y = e[i].to, z = e[i].v;
if(dis[y] > dis[x] * z) {
dis[y] = max((dis[x] * z + mod) % mod, 1ll);
q.push(make_pair(-dis[y], y));
}
}
}
}
inline long long read() {
long long f = 1, x = 0;
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;
}
int main() {
n = read(), m = read();
for(long long i = 1; i <= m; ++i) {
u = read(), v = read(), w = read();
a_e(u, v, w);
}
dj();
printf("%lld", dis[n]);
return 0;
}

浙公网安备 33010602011771号