1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| #include <cstdio> #include <algorithm> #include <cstring> #include <queue>
typedef std::pair<int, int> PII; inline int min(const int x, const int y) {return x < y ? x : y;} struct Edge { int to, nxt, w, a; } e[800005]; struct Node { int u, v, w, a; inline bool operator < (const Node x) const {return a > x.a;} } edge[400005]; bool done[200005]; int head[200005], dis[200005], tot, n, m; int fa[500005], up[500005][20], ans[500005], high[500005]; std::priority_queue<PII, std::vector<PII>, std::greater<PII> > Q; std::vector<int> sons[500005]; int find(const int x) {return fa[x] == x ? x : fa[x] = find(fa[x]);} inline void AddEdge(const int u, const int v, const int w, const int a) { e[++ tot].to = v, e[tot].w = w, e[tot].a = a; e[tot].nxt = head[u], head[u] = tot; }
void Dijkstra() { memset(dis, 0x3f, sizeof dis); memset(done, 0, sizeof done); Q.push(std::make_pair(dis[1] = 0, 1)); while (Q.size()) { int u(Q.top().second); Q.pop(); if (done[u]) continue; done[u] = true; for (int i(head[u]); i; i = e[i].nxt) { int v(e[i].to); if (dis[u] + e[i].w < dis[v]) Q.push(std::make_pair(dis[v] = dis[u] + e[i].w, v)); } } }
void dfs(const int u) { for (int i(1); i <= 19; ++ i) up[u][i] = up[up[u][i - 1]][i - 1]; for (int v : sons[u]) if (v != up[u][0]) up[v][0] = u, dfs(v); } void kruskal() { memset(ans, 0x3f, sizeof ans); std::sort(edge + 1, edge + m + 1); int cnt(0), k(0), now(n);//k表示当前考虑到了哪条边,cnt表示选了多少边,now表示最后一个新建点的编号 for (int i(1); i <= n; ++ i) ans[i] = dis[i], fa[i] = i; while (cnt < n - 1) { ++ k; int fx(find(edge[k].u)), fy(find(edge[k].v)); if (fx != fy) { ++ now, ++ cnt, fa[fx] = fa[fy] = fa[now] = now; sons[now].push_back(fx); sons[now].push_back(fy); high[now] = edge[k].a; ans[now] = min(ans[fx], ans[fy]); } } dfs(now); } int jump(int u, const int p) { for (int i(19); ~i; -- i) if (up[u][i] && high[up[u][i]] > p) u = up[u][i]; return ans[u]; }
int main() { int T; scanf("%d", &T); while (T --) { memset(head, 0, sizeof head); memset(up, 0, sizeof up); tot = 0; int q, k, s, last(0); scanf("%d%d", &n, &m); for (int i(1); i <= 2 * n + 1; ++ i) sons[i].clear(); for (int i(1); i <= m; ++ i) { int u, v, w, a; scanf("%d%d%d%d", &u, &v, &w, &a); AddEdge(u, v, w, a), AddEdge(v, u, w, a); edge[i].u = u, edge[i].v = v, edge[i].w = w, edge[i].a = a; } Dijkstra(); kruskal(); scanf("%d%d%d", &q, &k, &s); while (q --) { int v, p; scanf("%d%d", &v, &p); v = (v + k * last - 1) % n + 1; p = (p + k * last) % (s + 1); printf("%d\n", last = jump(v, p)); } } return 0; }
|