답안 #961989

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
961989 2024-04-13T01:54:17 Z pedroslrey Flood (IOI07_flood) C++17
73 / 100
257 ms 42588 KB
#include <bits/stdc++.h>

using namespace std;

class union_find {
private:
	vector<int> rep, rnk;

public:
	union_find(int n) : rep (n), rnk (n) {
		for (int i = 0; i < n; ++i)
			rep[i] = i;
	}

	int find(int u) {
		if (rep[u] == u) return u;
		return rep[u] = find(rep[u]);
	}

	void une(int u, int v) {
		u = find(u); v = find(v);

		if (u == v) return;
		if (rnk[u] > rnk[v]) swap(u, v);
		else if (rnk[u] == rnk[v]) ++rnk[v];

		rep[u] = v;
	}
};

struct edge {
	pair<int, int> p1, p2;
	int u, v;
	int id;

	static int cnt;

	edge(pair<int, int> d1, pair<int, int> d2, int k) :
		p1 (d1), p2 (d2), u (cnt++), v (cnt++), id (k) { }

	int side(pair<int, int> p) { return p == p1 ? u : v; }
	int other_side(pair<int, int> p) { return p == p1 ? v : u; }

	bool operator<(edge other) {
		pair<int, int> p = (p1 == other.p1 || p1 == other.p2 ? p1 : p2);

		pair<int, int> tp = (p1 == p ? p2 : p1), op = (other.p1 == p ? other.p2 : other.p1);

		auto val = [p](pair<int, int> q) {
			if (q.first > p.first) return 1;
			if (q.second > p.second) return 2;
			if (q.first < p.first) return 3;
			return 4;
		};

		return val(tp) < val(op);
	}
};

int edge::cnt = 0;

vector<int> bfs(vector<vector<int>> &graph, vector<int> &start) {
	int n = graph.size();

	queue<int> q;
	vector<bool> marc(n);
	for (int s: start) if (s < n) {
		q.push(s);
		marc[s] = true;

		// cerr << "starting on " << s << "\n";
	}

	vector<int> dist(n);

	while (!q.empty()) {
		int u = q.front(); q.pop();

		for (int v: graph[u])
			if (!marc[v]) {
				marc[v] = true;
				dist[v] = dist[u] + 1;
				q.push(v);
			}
	}

	return dist;
}

int main() {
	int n;
	cin >> n;

	vector<pair<int, int>> coords(n);
	for (auto &[x, y]: coords)
		cin >> x >> y;

	int m;
	cin >> m;

	vector<vector<edge>> walls(n);
	vector<int> height(2*m + 1);
	vector<bool> upper(2*m);
	vector<edge> all_walls;
	for (int i = 0; i < m; ++i) {
		int a, b;
		cin >> a >> b;

		--a; --b;

		edge e(coords[a], coords[b], i);

		height[e.u] = height[e.v] = e.p1.second;

		walls[a].push_back(e);
		walls[b].push_back(e);
		all_walls.push_back(e);

		if (e.p1.second == e.p2.second) {
			upper[e.side(min(e.p1, e.p2))] = true;
			// cerr << e.side(min(e.p1, e.p2)) << "\n";
		}
	}

	union_find regioes(2*m);
	for (int i = 0; i < n; ++i) {
		auto &viz = walls[i];
		auto p = coords[i];
		sort(viz.begin(), viz.end());

		for (int i = 0; i < viz.size(); ++i)
			regioes.une(viz[i].side(p), viz[(i + 1)%viz.size()].other_side(p));
	}

	vector<vector<int>> graph(2*m);
	union_find comps = regioes;
	for (auto &e: all_walls) {
		int ru = regioes.find(e.u), rv = regioes.find(e.v);
		if (ru != rv) {
			graph[ru].push_back(rv);
			graph[rv].push_back(ru);
			comps.une(ru, rv);

			// cerr << ru << " " << rv << "\n";
		}
	}

	vector<int> tallest(2*m, 2*m);
	for (int i = 0; i < 2*m; ++i) if (upper[i]) {
		int c = comps.find(i);
		if (height[tallest[c]] < height[i])
			tallest[c] = i;
	}

	for (int &x: tallest) if (x != 2*m) {
		// cerr << x << " TALLEST OF " << comps.find(x) << " " << height[x] << "\n";
		x = regioes.find(x);
	}

	sort(tallest.begin(), tallest.end());
	tallest.erase(unique(tallest.begin(), tallest.end()), tallest.end());

	auto dist = bfs(graph, tallest);

	vector<int> ans;
	for (edge e: all_walls)
		if (dist[regioes.find(e.u)] == dist[regioes.find(e.v)])
			ans.push_back(e.id + 1);

	cout << ans.size() << "\n";
	for (int x: ans)
		cout << x << "\n";
}

Compilation message

flood.cpp: In function 'int main()':
flood.cpp:131:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<edge>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  131 |   for (int i = 0; i < viz.size(); ++i)
      |                   ~~^~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 348 KB Output is correct
2 Correct 0 ms 352 KB Output is correct
3 Correct 1 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 348 KB Output is correct
2 Correct 1 ms 440 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 344 KB Output is correct
2 Correct 1 ms 344 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 344 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 348 KB Output is correct
2 Correct 1 ms 604 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 344 KB Output is correct
2 Correct 1 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 28 ms 5548 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 101 ms 20256 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 102 ms 22820 KB Output is correct
2 Runtime error 202 ms 39240 KB Memory limit exceeded
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 182 ms 30856 KB Output is correct
2 Runtime error 257 ms 42588 KB Memory limit exceeded
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 233 ms 35688 KB Memory limit exceeded
2 Halted 0 ms 0 KB -