題目大意:有一張$n$個點$m$條邊的圖,每一個邊有兩個屬性$a_i,b_i$。有$Q$個詢問,每一個詢問給出$v,p$,表示全部邊中$b_i\leqslant p$的邊會被標記,在點$v$,能夠經過不被標記的邊到達任意點,而後用最小的$\sum a_i$到達點$1$,輸出這個最小值。多組數據ios
$n\leqslant2\times10^5,m\leqslant4\times10^5$,最多$3$組數據。spa
題解:$\mathrm{kruskal}$重構樹,按$b_i$從大到小建重構樹,能夠發現若一個點沒有被標記,它的子樹內均不被標記,因此能夠由點$1$跑最短路,而後記錄每一個節點的子樹內最近的值。注意,$\mathrm{SPFA}$已死,要用$\mathrm{dijkstra}$。blog
卡點:多組數據中清空錯誤ci
C++ Code:get
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> const int maxn = 6e5 + 10; int Tim, n, m, N, Q, K, S, f[maxn], w[maxn]; int _u[maxn], _v[maxn], _l[maxn], _a[maxn], rnk[maxn]; inline bool cmp(int a, int b) { return _a[a] > _a[b]; } int find(int x) { return x == f[x] ? x : (f[x] = find(f[x])); } long long dis[maxn]; namespace Graph { int head[maxn], cnt; struct Edge { int to, nxt, w; } e[maxn << 1]; void addedge(int a, int b, int c) { e[++cnt] = (Edge) { b, head[a], c }; head[a] = cnt; e[++cnt] = (Edge) { a, head[b], c }; head[b] = cnt; } void clear() { memset(head, 0, sizeof head), cnt = 0; } int V[maxn << 2]; inline int getmin(int a, int b) { return dis[a] < dis[b] ? a : b; } void modify(int rt, int l, int r, int p, int v) { if (l == r) { V[rt] = v; return ; } int mid = l + r >> 1; if (p <= mid) modify(rt << 1, l, mid, p, v); else modify(rt << 1 | 1, mid + 1, r, p, v); V[rt] = getmin(V[rt << 1], V[rt << 1 | 1]); } void dijkstra(int S) { memset(dis, 0x3f, sizeof dis), memset(V, 0, sizeof V); dis[S] = 0, modify(1, 1, n, S, S); for (int Tim = n; Tim; --Tim) { int u = V[1]; modify(1, 1, n, u, 0); for (int i = head[u], v; i; i = e[i].nxt) { v = e[i].to; if (dis[v] > dis[u] + e[i].w) dis[v] = dis[u] + e[i].w, modify(1, 1, n, v, v); } } } } const int M = 24; int fa[maxn][M + 1]; void addedge(int a, int b) { fa[b][0] = a, dis[a] = std::min(dis[a], dis[b]); } long long query(int v, int p) { for (int i = M; ~i; --i) if (w[fa[v][i]] > p) v = fa[v][i]; return dis[v]; } int main() { std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0); std::cin >> Tim; while (Tim --> 0) { Graph::clear(), w[0] = -0x3f3f3f3f, memset(fa, 0, sizeof fa); std::cin >> n >> m, N = n; for (int i = 0, l; i < m; ++i) { std::cin >> _u[i] >> _v[i] >> l >> _a[i]; Graph::addedge(_u[i], _v[i], l); rnk[i] = i; } Graph::dijkstra(1); for (int i = 1; i <= n + m; ++i) f[i] = i; std::sort(rnk, rnk + m, cmp); for (int i = 0, u, v; i < m; ++i) { u = find(_u[rnk[i]]), v = find(_v[rnk[i]]); if (u != v) { addedge(++N, u), addedge(N, v); w[N] = _a[rnk[i]], f[u] = f[v] = N; } } for (int i = 1; i <= M; ++i) for (int j = 1; j <= N; ++j) fa[j][i] = fa[fa[j][i - 1]][i - 1]; std::cin >> Q >> K >> S; long long v, p, ans = 0; while (Q --> 0) { std::cin >> v >> p; if (K) v = (v + ans - 1) % n + 1, p = (p + ans) % (S + 1); ans = query(v, p); std::cout << ans << '\n'; } } return 0; }