[UOJ # 393]] [NOI2018 Return Journey

Title effect: There is a point $ $ $ n-m of FIG $ edges, each side has two attributes $ a_i, b_i $. There is a $ Q $ query, asking each given $ v, p $, showing all sides $ b_i \ leqslant p $ edge will be marked, V $ $ point, any point can be reached by not marked edge , then the minimum $ \ sum a_i $ $ 1 $ reaching point, the output of the minimum value. Multiple sets of data

$ N \ leqslant2 \ times10 ^ 5, m \ leqslant4 \ times10 ^ 5 $, $ 3 $ sets up data.

Interpretations: $ \ mathrm {} $ Kruskal tree reconstructed, by descending built $ $ B_i reconstructed tree, can be found if a point is not marked, not marked within its subtree, the point can be $ 1 $ shortest run, and then record the most recent value of the sub-tree of each node. Note, $ \ mathrm {SPFA} $ is dead, use the $ \ mathrm {dijkstra} $.

Point card: multiple sets of data, clear the error

 

C++ Code:

#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,years = 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;
}

  

Guess you like

Origin www.cnblogs.com/Memory-of-winter/p/11628351.html