又是一年,重写删边最短路又炸了。。。。 码风良好,Hack 和 #2~10 都过了。 可能是求 L,R 数组的问题,因为这个我没按 Sol 写。我这里的 L,R 保存的是边的编号。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
typedef pair<int, int> PII;
#define fi first
#define se second
int n, m;
int pre[N], d[N], L[N], R[N], id[N << 2], rd[N];
int h[N], e[N << 2], ne[N << 2], w[N << 2], idx;
bool st[N << 2];
int mx[N << 4];
int res, c;
void add(int a, int b, int c) {
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
e[idx] = a, w[idx] = c, ne[idx] = h[b], h[b] = idx ++ ;
}
void dijkstra(int s) {
memset(d, 0x3f, sizeof d); d[s] = 0;
priority_queue<PII, vector<PII>, greater<PII> > heap; heap.push({0, s});
while (heap.size()) {
PII t = heap.top(); heap.pop();
if (t.fi != d[t.se]) continue ;
for (int _ = h[t.se]; ~_; _ = ne[_]) if (d[e[_]] > t.fi + w[_]) {
d[e[_]] = t.fi + w[_]; pre[e[_]] = _; heap.push({d[e[_]], e[_]});
}
}
}
void modify(int l, int r, int ql, int qr, int w, int x) {
if (l > r) return ;
if (l >= ql && r <= qr) return mx[x] = min(mx[x], w), void();
int mid = l + r >> 1; if (ql <= mid) modify(l, mid, ql, qr, w, x << 1);
if (qr > mid) modify(mid + 1, r, ql, qr, w, x << 1 | 1);
}
void upd(int l, int r, int x) {
if (l > r) return ;
mx[x] = min(mx[x], mx[x >> 1]);
if (l == r) {
if (mx[x] > res) res = mx[x], c = 1;
else if (mx[x] == res) c ++ ; return ;
} int mid = l + r >> 1;
upd(l, mid, x << 1), upd(mid + 1, r, x << 1 | 1);
}
int main() {
scanf("%d%d", &n, &m); memset(h, -1, sizeof h); memset(L, -1, sizeof L); memset(R, -1, sizeof R);
for (int i = 1, u, v, w; i <= m; i ++ ) { scanf("%d%d%d", &u, &v, &w); add(u, v, w); }
dijkstra(n); memcpy(rd, d, sizeof d); int ed = 1, cnt = 0;
while (ed != n) id[pre[ed]] = id[pre[ed] ^ 1] = ++ cnt, R[ed] = cnt, ed = e[pre[ed] ^ 1]; R[n] = cnt + 1;
for (int i = 1; i <= n; i ++ ) { if (~R[i]) continue ;
if (d[i] > 1e9) { R[i] = -1; continue ; }
int fa = i; while (R[fa] == -1) fa = e[pre[fa] ^ 1];
R[i] = R[fa];
}
dijkstra(1); ed = n;
while (ed != 1) st[pre[ed]] = st[pre[ed] ^ 1] = 1, L[ed] = id[pre[ed]], ed = e[pre[ed] ^ 1]; L[1] = 0;
for (int i = 1; i <= n; i ++ ) { if (~L[i]) continue ;
if (d[i] > 1e9) { L[i] = -1; continue ; }
int fa = i; while (L[fa] == -1) fa = e[pre[fa] ^ 1];
L[i] = L[fa];
}
res = 0, c = 0; memset(mx, 0x3f, sizeof mx);
for (int i = 1; i <= n; i ++ ) for (int _ = h[i]; ~_; _ = ne[_]) {
if (st[_]) continue ;
if (L[i] >= 0 && R[e[_]] >= 0 && L[i] < R[e[_]] - 1) modify(1, cnt, L[i] + 1, R[e[_]] - 1, rd[e[_]] + d[i] + w[_], 1);
} upd(1, cnt, 1); if (res == d[n]) c = m; printf("%d %d\n", res, c); return 0;
}