답안 #227008

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
227008 2020-04-25T20:50:04 Z abeker Matching (COCI20_matching) C++17
58 / 110
2037 ms 524292 KB
#include <bits/stdc++.h>
using namespace std;

typedef pair <int, int> pii;

const int MAXN = 1e5 + 5;
const int offset = 1 << 17;

class TwoSat {
	int n;
	vector <int> sol;
	vector <bool> bio;
	vector <int> comp;
	vector <vector <int>> adj, rev;
	stack <int> order;
	public:
		int add_variables(int vars) {
			n += vars;
			for (int i = 0; i < 2 * vars; i++) {
				sol.push_back(0);
				bio.push_back(false);
				comp.push_back(0);
				adj.push_back(vector <int> ());
				rev.push_back(vector <int> ());
			}
			return n - vars;
		}
		TwoSat(int _n) {
			n = 0;
			add_variables(_n);
		}
		TwoSat(){}
		void add_edge(int u, int v) {
			adj[u].push_back(v);
			rev[v].push_back(u);
		}
		void add_implication(int u1, int neg1, int u2, int neg2) {
			add_edge(2 * u1 + neg1, 2 * u2 + neg2);
			add_edge(2 * u2 + !neg2, 2 * u1 + !neg1);
		}
		void set_variable(int u, bool val) {
			add_implication(u, val, u, !val);
		}
		void at_most_one(const vector <pii> &v) {
			int sz = v.size();
			add_variables(sz);
			for (int i = 0; i < sz; i++) {
				add_implication(v[i].first, v[i].second, n - i - 1, 0);
				if (i) {
					add_implication(n - i, 0, n - i - 1, 0);
					add_implication(n - i, 0, v[i].first, !v[i].second);
				}
			}
		}
		void dfs_forward(int x) {
			bio[x] = true;
			for (auto it : adj[x])
				if (!bio[it])
					dfs_forward(it);
			order.push(x);
		}
		void dfs_backward(int x, int c) {
			comp[x] = c;
			for (auto it : rev[x])
				if (!comp[it])
					dfs_backward(it, c);
		}
		bool solve() {
			for (int i = 0; i < 2 * n; i++)
				if (!bio[i])
					dfs_forward(i);
			int ptr = 0;
			for (; !order.empty(); order.pop())
				if (!comp[order.top()])
					dfs_backward(order.top(), ++ptr);
			for (int i = 0; i < 2 * n; i++) {
				if (comp[i] == comp[i ^ 1])
					return false;
				sol[i] = comp[i] > comp[i ^ 1];
			}
			return true;
		}
		int get(int u, int neg) {
			return sol[2 * u + neg];
		}
};

int N;
int x[MAXN], y[MAXN];
vector <pii> tour[2 * offset];
int st[2 * offset], off[2 * offset];
vector <int> hor[MAXN], ver[MAXN];
unordered_map <int, pii> segs;
vector <int> adj[MAXN];
TwoSat Segments;

void load() {
	scanf("%d", &N);
	for (int i = 0; i < N; i++) {
		scanf("%d%d", x + i, y + i);
		hor[y[i]].push_back(i);
		ver[x[i]].push_back(i);
	}
}

void insert(int x, int lo, int hi, int from, int to, int var, int height) {
	if (lo >= to || hi <= from)	
		return;
	if (lo >= from && hi <= to) {
		tour[x].push_back({height, var});
		return;
	}
	int mid = (lo + hi) / 2;
	insert(2 * x, lo, mid, from, to, var, height);
	insert(2 * x + 1, mid, hi, from, to, var, height);
}
	
void init(int x) {
	if (tour[x].empty())
		return;
	off[x] = 1;
	sort(tour[x].begin(), tour[x].end());
	while (off[x] < tour[x].size())
		off[x] *= 2;
	st[x] = Segments.add_variables(2 * off[x]);
	for (int i = 0; i < off[x]; i++) {
		Segments.add_implication(st[x] + 2 * i, 0, st[x] + i, 0);
		Segments.add_implication(st[x] + 2 * i + 1, 0, st[x] + i, 0);
	}
	for (int i = 0; i < tour[x].size(); i++)
		Segments.add_implication(tour[x][i].second, 0, st[x] + i + off[x], 0);
}

int get_bounds(int x, int val) {
	return lower_bound(tour[x].begin(), tour[x].end(), pii(val, 0)) - tour[x].begin();
}

void update(int node, int x, int lo, int hi, int from, int to, int var) {
	if (lo >= to || hi <= from)
		return;
	if (lo >= from && hi <= to) {
		Segments.add_implication(st[node] + x, 0, var, 1);
		return;
	}
	int mid = (lo + hi) / 2;
	update(node, 2 * x, lo, mid, from, to, var);
	update(node, 2 * x + 1, mid, hi, from, to, var);
}

void add_intersections(int x, int down, int up, int var) {
	for (x += offset; x; x /= 2) 
		if (off[x])
			update(x, 1, 0, off[x], get_bounds(x, down), get_bounds(x, up + 1), var);
}

void bye() {
	puts("NE");
	exit(0);
}

void solve() {
	for (int i = 1; i < MAXN; i++) 
		if (hor[i].size() == 2) {
			int tmp = Segments.add_variables(1);
			segs[tmp] = {hor[i][0], hor[i][1]};
			int l = MAXN, r = 0;
			for (auto it : hor[i]) {
				adj[it].push_back(tmp);
				l = min(l, x[it]);
				r = max(r, x[it]);
			}
			insert(1, 0, offset, l, r + 1, tmp, i);
		}
	
	for (int i = 0; i < 2 * offset; i++)
		init(i);
	
	for (int i = 1; i < MAXN; i++) 
		if (ver[i].size() == 2) {
			int tmp = Segments.add_variables(1);
			segs[tmp] = {ver[i][0], ver[i][1]};
			int l = MAXN, r = 0;
			for (auto it : ver[i]) {
				adj[it].push_back(tmp);
				l = min(l, y[it]);
				r = max(r, y[it]);
			}
			add_intersections(i, l, r, tmp);
		}
	
	for (int i = 0; i < N; i++) 
		if (!adj[i].empty())
			Segments.add_implication(adj[i][0], 1, adj[i][1 % adj[i].size()], 0);
		else
			bye();
	
	if (!Segments.solve())
		bye();
	
	puts("DA");
	for (auto it : segs)
		if (Segments.get(it.first, 0))
			printf("%d %d\n", it.second.first + 1, it.second.second + 1);
}

int main() {
	load();
	solve();
	return 0;
}

Compilation message

matching.cpp: In function 'void init(int)':
matching.cpp:123:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  while (off[x] < tour[x].size())
         ~~~~~~~^~~~~~~~~~~~~~~~
matching.cpp:130:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for (int i = 0; i < tour[x].size(); i++)
                  ~~^~~~~~~~~~~~~~~~
matching.cpp: In function 'void load()':
matching.cpp:98:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d", &N);
  ~~~~~^~~~~~~~~~
matching.cpp:100:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d%d", x + i, y + i);
   ~~~~~^~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 14 ms 13952 KB Output is correct
2 Correct 14 ms 13824 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 14 ms 13952 KB Output is correct
2 Correct 14 ms 13824 KB Output is correct
3 Correct 13 ms 13824 KB Output is correct
4 Correct 14 ms 13832 KB Output is correct
5 Correct 16 ms 13824 KB Output is correct
6 Correct 14 ms 13952 KB Output is correct
7 Correct 13 ms 13824 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 14 ms 13952 KB Output is correct
2 Correct 14 ms 13824 KB Output is correct
3 Correct 13 ms 13824 KB Output is correct
4 Correct 14 ms 13832 KB Output is correct
5 Correct 16 ms 13824 KB Output is correct
6 Correct 14 ms 13952 KB Output is correct
7 Correct 13 ms 13824 KB Output is correct
8 Correct 13 ms 14080 KB Output is correct
9 Correct 18 ms 14080 KB Output is correct
10 Correct 13 ms 14208 KB Output is correct
11 Correct 14 ms 14080 KB Output is correct
12 Correct 13 ms 14080 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 14 ms 13952 KB Output is correct
2 Correct 14 ms 13824 KB Output is correct
3 Correct 13 ms 13824 KB Output is correct
4 Correct 14 ms 13832 KB Output is correct
5 Correct 16 ms 13824 KB Output is correct
6 Correct 14 ms 13952 KB Output is correct
7 Correct 13 ms 13824 KB Output is correct
8 Correct 13 ms 14080 KB Output is correct
9 Correct 18 ms 14080 KB Output is correct
10 Correct 13 ms 14208 KB Output is correct
11 Correct 14 ms 14080 KB Output is correct
12 Correct 13 ms 14080 KB Output is correct
13 Correct 29 ms 20456 KB Output is correct
14 Correct 31 ms 20260 KB Output is correct
15 Correct 29 ms 20464 KB Output is correct
16 Correct 32 ms 20460 KB Output is correct
17 Correct 40 ms 20328 KB Output is correct
18 Correct 31 ms 20336 KB Output is correct
19 Correct 33 ms 20336 KB Output is correct
20 Correct 30 ms 20464 KB Output is correct
21 Correct 30 ms 20336 KB Output is correct
22 Correct 29 ms 20336 KB Output is correct
23 Correct 35 ms 20448 KB Output is correct
24 Correct 38 ms 20584 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 14 ms 13952 KB Output is correct
2 Correct 14 ms 13824 KB Output is correct
3 Correct 13 ms 13824 KB Output is correct
4 Correct 14 ms 13832 KB Output is correct
5 Correct 16 ms 13824 KB Output is correct
6 Correct 14 ms 13952 KB Output is correct
7 Correct 13 ms 13824 KB Output is correct
8 Correct 13 ms 14080 KB Output is correct
9 Correct 18 ms 14080 KB Output is correct
10 Correct 13 ms 14208 KB Output is correct
11 Correct 14 ms 14080 KB Output is correct
12 Correct 13 ms 14080 KB Output is correct
13 Correct 29 ms 20456 KB Output is correct
14 Correct 31 ms 20260 KB Output is correct
15 Correct 29 ms 20464 KB Output is correct
16 Correct 32 ms 20460 KB Output is correct
17 Correct 40 ms 20328 KB Output is correct
18 Correct 31 ms 20336 KB Output is correct
19 Correct 33 ms 20336 KB Output is correct
20 Correct 30 ms 20464 KB Output is correct
21 Correct 30 ms 20336 KB Output is correct
22 Correct 29 ms 20336 KB Output is correct
23 Correct 35 ms 20448 KB Output is correct
24 Correct 38 ms 20584 KB Output is correct
25 Correct 1136 ms 190708 KB Output is correct
26 Correct 1087 ms 190196 KB Output is correct
27 Correct 1131 ms 190236 KB Output is correct
28 Correct 1099 ms 191168 KB Output is correct
29 Correct 1078 ms 190320 KB Output is correct
30 Correct 1093 ms 190452 KB Output is correct
31 Correct 1078 ms 189860 KB Output is correct
32 Correct 1060 ms 189692 KB Output is correct
33 Correct 947 ms 179804 KB Output is correct
34 Correct 1253 ms 179932 KB Output is correct
35 Correct 741 ms 179804 KB Output is correct
36 Runtime error 2037 ms 524292 KB Execution killed with signal 9 (could be triggered by violating memory limits)
37 Halted 0 ms 0 KB -