Submission #1234367

#TimeUsernameProblemLanguageResultExecution timeMemory
1234367hashdfdfhBitaro’s Party (JOI18_bitaro)C++20
14 / 100
2101 ms211188 KiB
#include <bits/stdc++.h>
using namespace std;

const int MAX_N = 1e5 + 5;
const int BASE = 150;

// 保存原始边信息
vector<int> edges[MAX_N];

// 保存和u距离 最远的BASE个node信息
// first:距离
// second:节点编号
vector<pair<int, int>> maxb[MAX_N];

// 保存到u的最远距离
int dist[MAX_N];

// 0表示可用,1表示被禁止
int tag[MAX_N];

int n, m, q;

void process() {
	int start, y;
	cin >> start >> y;

	// 如果禁用比较多
	if (y >= BASE) {
		// 初始化距离为-1
		memset(dist, -1, sizeof(dist));
		memset(tag, 0, sizeof(tag));

		// 读取y个禁用点
		for (int i = 0; i < y; i++) {
			int x;
			cin >> x;
			tag[x] = 1;
		}

		// 因为边肯定小->大, 直接遍历就可以
		for (int u = 1; u <= n; u++) {
			// 如果没有被禁用,但是仍然是-1的,认为是0
			if (!tag[u] && dist[u] == -1) {
				dist[u] = 0;
			}

			// 如果仍然是-1的,说明不可达
			if (dist[u] == -1) {
				continue;
			}
			for (auto v : edges[u]) {
				dist[v] = max(dist[v], dist[u] + 1);
			}
		}
		cout << dist[start] << endl;
	}
	// 如果禁用比较少
	else {
		memset(tag, 0, sizeof(tag));

		// 读取y个禁用点
		for (int i = 0; i < y; i++) {
			int x;
			cin >> x;
			tag[x] = 1;
		}

		int maxv = -1;

		// 遍历和start最远的BASE个
		for (auto v : maxb[start]) {
			// 如果没有被禁用掉
			if (!tag[v.second]) {
				maxv = v.first;
				break;
			}
		}

		cout << maxv << endl;
	}
}

void merge(int u, int v) {
	memset(tag, false, sizeof(tag));
	vector<pair<int, int>> nw;
	int it1 = 0, it2 = 0;
	while (((it1 != maxb[u].size()) || (it2 != maxb[v].size())) && (nw.size() < BASE)) {
		if (it1 == maxb[u].size()) {
			if (tag[maxb[v][it2].second]) {
				it2++;
				continue;
			}  tag[maxb[v][it2].second] = 1;
			nw.push_back(maxb[v][it2]);
			it2++;
			continue;
		}
		if (it2 == maxb[v].size()) {
			if (tag[maxb[u][it1].second]) {
				it1++;
				continue;
			} tag[maxb[u][it1].second] = 1;
			auto t = maxb[u][it1];
			t.first++;
			nw.push_back(t);
			it1++;
			continue;
		}
		if (maxb[u][it1].first + 1 > maxb[v][it2].first) {
			if (tag[maxb[u][it1].second]) {
				it1++;
				continue;
			} tag[maxb[u][it1].second] = 1;
			auto t = maxb[u][it1];
			t.first++;
			nw.push_back(t);
			it1++;
			continue;
		}
		else {
			if (tag[maxb[v][it2].second]) {
				it2++;
				continue;
			} tag[maxb[v][it2].second] = 1;
			nw.push_back(maxb[v][it2]);
			it2++;
			continue;
		}
	}
	swap(nw, maxb[v]);
	nw.clear();
}

signed main() {
	cin >> n >> m >> q;

	// 读取边信息
	for (int i = 1; i <= m; i++) {
		int u, v;
		cin >> u >> v;

		// 保存原始图
		edges[u].push_back(v);
	}

	for (int u = 1; u <= n; u++) {
		// 如果到u的最大距离还不足,那么u本身也算
		if (maxb[u].size() < BASE) {
			maxb[u].push_back(make_pair(0, u));
		}
		for (auto v : edges[u]) {
			merge(u, v);
		}
	}

	for (int i = 0; i < q; ++i) {
		process();
	}
	return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...