爱上火车之铁路崩溃问题 | 题解 | belong to 魔怔入の躺尸自创
link
突然想起来自己还出过一道题来着,写个题解?
一眼最短路模板,多维护一个名为断裂的边权就可以了,若断裂则直接停止转移即可。
唯一用点脑子的是怎么处理抽象读入,实际上会用 map 就可以解决。
复杂度大概是 \(O((n+m)\log n)\),实际上 \(O((n+m){\log n}^2)\) 稍微优化(mp.count)也过了。
题外话:
一开始本来想卡掉 map 的,不过发现卡掉 map 的数据有点点大,(也导致了这个抽象的数据范围),后来又发现加上 count 后根本卡不掉……遂摆烂,数据范围也没有改回去,至少顺带卡掉了 spfa ,后来被同学理论 \(O(n^2)\) 但跑不满光速草过,大怒,作 Hack_n2 数据。
说是要给出 stl 二倍的时空,我 stl 严格卡常也不为过吧(
以后再也不出题了,尤其是这么唐诗的……
code
#include <bits/extc++.h>
//#define submit
#ifdef submit
#define getchar getchar_unlocked
#define putchar putchar_unlocked
#endif
#define e_ putchar(' ')
#define en_ putchar('\n')
using namespace std;
inline int in() {
int n = 0; char p = getchar();
while(p < '-') p = getchar();
// bool f = p == '-' ? p = getchar() : 0;
do n = (n << 1) + (n << 3) + (p ^ 48), p = getchar();
while(isdigit(p));
// return f ? -n : n;
return n;
}
template <typename T> inline void in(T &n) { n = in();}
inline void out(int x) {
if(x < 0) putchar('-'), x = -x;
if (x >= 10) out(x / 10);
putchar(x % 10 + '0');
}
constexpr int N = 400010;
typedef pair<int, int> node;
int n, m, k, dis[N];
bool vis[N];
vector<node>e[N]; // 改成链式前向星还能卡卡,但是懒
unordered_map<int, int>mp;
std::priority_queue<node>q;
void dij(int s) {
memset(dis, 63, (n + 1) << 2);
dis[s] = 0;
q.push({0, s});
while(!q.empty()) {
int u = q.top().second;
q.pop();
if(vis[u])continue;
vis[u] = 1;
for(node v : e[u]) {
if(dis[v.first] > dis[u] + v.second) { // 太长就拆开了
if(!mp.count(v.first + u * 10001) || dis[u] + v.second <= mp[v.first + u * 10001]) {
dis[v.first] = dis[u] + v.second;
q.push({-dis[v.first], v.first});
}
}
}
}
}
signed main() {
in(n); in(m), in(k);
int u, v, w;
for(int i = 1; i <= m; i++) {
u = in(), v = in(), w = in();
e[u].push_back({v, w});
e[v].push_back({u, w});
}
for(int i = 1; i <= k; i++) {
u = in(), v = in(), w = in();
mp[u + v * 10001] = mp[v + u * 10001] = w;
}
dij(1);
out(dis[n] == dis[0] ? -1 : dis[n]); en_;
return 0;
}

浙公网安备 33010602011771号