公式

C - Virus 解説 by en_translator


Consider a graph with \(N\) vertices \(1,2, \ldots, N\), where there is an undirected edge between vertex \(i\) and \(j\) if and only if the distance between \((X_i,Y_i)\) and \((X_j,Y_j)\) is \(D\) or less.

Person \(i\) is infected with the virus if and only if there is a path from vertex \(1\) to vertex \(i\) in the graph defined above, i.e. vertex \(1\) and vertex \(i\) belongs to the same connected component.

Therefore, we can obtain the correct answer by a graph-searching algorithm such as DFS (Depth-First Search), BFS (Breadth-First Search), or DSU (Disjoint Set Union).

If you use DFS or BFS, the time complexity is \(O(N^2)\) because there are \(N\) vertices and \(O(N^2)\) edges; if you use DSU, the complexity is a bit worse, but it is still fast enough.

Sample code

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int main() {
	int n, d;
	cin >> n >> d;
	vector<int> x(n), y(n);
	for (int i = 0; i < n; i++) cin >> x[i] >> y[i];
	vector<vector<bool>> graph(n, vector<bool>(n));
	for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) if ((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]) <= d * d) graph[i][j] = true;
	vector<bool> ans(n);
	ans[0] = true;
	queue<int> que; que.push(0);
	while (!que.empty()) {
		int q = que.front(); que.pop();
		for (int i = 0; i < n; i++) {
			if (graph[q][i] && !ans[i]) {
				ans[i] = true;
				que.push(i);
			}
		}
	}
	for (int i = 0; i < n; i++) cout << (ans[i] ? "Yes" : "No") << '\n';
}

投稿日時:
最終更新: