我自己写这个题的时候,想到了按 r 降序,但是实现的时候并没有想到题解区里的当前弧优化的写法或者是 vector popback 的写法。
所以我的写法是,用 set 凑合一下,不要的边暴力删掉就好了:
ll dis[MAXN];
bool inq[MAXN];
void spfa(int S) {
rep(u, 1, n)
dis[u] = INF;
dis[S] = 0;
queue<int> q;
q.push(S), inq[S] = true;
while (!q.empty()) {
int u = q.front(); q.pop(), inq[u] = false;
while (!G[u].empty()) {
auto [v, r, s] = G[u].back();
if (r >= dis[u] + a[u] * (u != 1)) {
if (dis[v] > s) {
dis[v] = s;
if (!inq[v])
q.push(v), inq[v] = true;
}
G[u].pop_back();
} else
break;
}
}
}
但是我 Edge 的定义是:
struct Edge {
int v;
ll r, s;
Edge(int v, ll r, ll s) : v(v), r(r), s(s) {}
friend bool operator<(Edge A, Edge B) {
return A.r < B.r;
}
};
注意这个小于号。这意味着,如果两条边的 r 相同,则它们会被 set 的去重搞没。然后就 50pts 了。