bzoj4400
/* * 此题同bzoj2725 * 增加了枚举边的操作 */ #include <bits/stdc++.h> const int N = 2e5 + 10;// oo = 999999999; #define LL long long const LL oo = 9e18; int n, m, S, T; int Short_path[N], Snum[N], Tnum[N], Id[N], path_js; bool vis[N]; int head[N], now; struct Node {int u, v, w, nxt;} G[N << 1]; LL dis_s[N], dis_t[N]; LL Minn[N << 2], Ans[N]; inline void Add(int u, int v, int w) { G[++ now].v = v, G[now].w = w, G[now].nxt = head[u], head[u] = now; } struct Node_ { int u; LL dis; bool operator < (const Node_ a) const {return dis > a.dis;} }; std:: priority_queue <Node_> Q; void Dijkstra(int start, LL dis_[]) { for(int i = 1; i <= n; i ++) dis_[i] = oo, vis[i] = 0; Node_ now; now = (Node_) {start, 0}; dis_[start] = 0; Q.push(now); while(!Q.empty()) { Node_ topp = Q.top(); Q.pop(); if(vis[topp.u]) continue; vis[topp.u] = 1; for(int i = head[topp.u]; ~ i; i = G[i].nxt) { int v = G[i].v; if(dis_[v] > dis_[topp.u] + G[i].w) { dis_[v] = dis_[topp.u] + G[i].w; Q.push((Node_) {v, dis_[v]}); } } } } inline void Bfs(int x, LL dis_[], int bel[]) { std:: queue <int> Q1; Q1.push(Short_path[x]); bel[Short_path[x]] = x; while(!Q1.empty()) { int topp = Q1.front(); Q1.pop(); for(int i = head[topp]; ~ i; i = G[i].nxt) { int v = G[i].v; if(!Id[v] && !bel[v] && dis_[v] == dis_[topp] + G[i].w) { bel[v] = x; Q1.push(v); } } } } #define lson jd << 1 #define rson jd << 1 | 1 void Sec_G(int l ,int r, int jd, int x, int y, LL num) { if(x <= l && r <= y) { Minn[jd] = std:: min(Minn[jd], (LL)num); return ; } int mid = (l + r) >> 1; if(x <= mid) Sec_G(l, mid, lson, x, y, num); if(y > mid) Sec_G(mid + 1, r, rson, x, y, num); } void Dfs_tree(int l, int r, int jd) { if(l == r) { Ans[l] = Minn[jd]; return ; } int mid = (l + r) >> 1; Minn[lson] = std:: min(Minn[lson], Minn[jd]); Minn[rson] = std:: min(Minn[rson], Minn[jd]); Dfs_tree(l, mid, lson), Dfs_tree(mid + 1, r, rson); } #define gc getchar() inline LL read() { LL x = 0; char c = gc; while(c < '0' || c > '9') c = gc; while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x; } bool visit[N << 1]; int main() { n = read(), m = read(); for(int i = 1; i <= (N << 2); i ++) Minn[i] = oo; for(int i = 1; i <= n; i ++) head[i] = -1; for(int i = 1; i <= m; i ++) { int u = read(), v = read(), w = read(); Add(u, v, w), Add(v, u, w); } S = 1, T = n; Dijkstra(S, dis_s); Dijkstra(T, dis_t); for(int i = S; i != T; i = i) { // visit[i] = 1; Short_path[++ path_js] = i; Id[i] = path_js; for(int j = head[i]; ~ j; j = G[j].nxt) { if(dis_t[i] == G[j].w + dis_t[G[j].v]) { i = G[j].v; visit[j] = 1; break; } } } Short_path[path_js + 1] = T, Id[T] = path_js + 1; for(int i = 1; i <= path_js; i ++) Bfs(i, dis_s, Snum); for(int i = path_js + 1; i >= 1; i --) Bfs(i, dis_t, Tnum); for(int i = 1; i <= n; i ++) { for(int j = head[i]; ~ j; j = G[j].nxt) { int v = G[j].v; if(visit[j]) continue; if(Snum[i] < Tnum[v] && Snum[i] && Tnum[v]) { Sec_G(1, path_js, 1, Snum[i], Tnum[v] - 1, dis_s[i] + G[j].w + dis_t[v]); } } } Dfs_tree(1, path_js, 1); LL Dis = 0, js; for(int i = 1; i <= path_js; i ++) { if(Ans[i] > Dis && Ans[i] != oo) Dis = Ans[i], js = 1; else if(Ans[i] == Dis) js ++; } if(Dis == dis_s[T]) js += m - path_js; std:: cout << Dis << " " << js; return 0; } ?