답안 #227015

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
227015 2020-04-25T21:05:45 Z abeker Matching (COCI20_matching) C++17
58 / 110
2500 ms 436940 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 add_clause(int x, int u, int v) {
	if (u < off[x] + tour[x].size())
		Segments.add_implication(u < off[x] ? st[x] + u : tour[x][u - off[x]].second, 0, st[x] + v, 0);
}
	
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++) {
		add_clause(x, 2 * i, i);
		add_clause(x, 2 * i + 1, i);
	}
}

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(x < off[node] ? st[node] + x : tour[node][x - off[node]].second, 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 add_clause(int, int, int)':
matching.cpp:119:8: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  if (u < off[x] + tour[x].size())
      ~~^~~~~~~~~~~~~~~~~~~~~~~~~
matching.cpp: In function 'void init(int)':
matching.cpp:128:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  while (off[x] < tour[x].size())
         ~~~~~~~^~~~~~~~~~~~~~~~
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 13 ms 13824 KB Output is correct
2 Correct 13 ms 13824 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 13 ms 13824 KB Output is correct
2 Correct 13 ms 13824 KB Output is correct
3 Correct 13 ms 13824 KB Output is correct
4 Correct 13 ms 13824 KB Output is correct
5 Correct 13 ms 13824 KB Output is correct
6 Correct 13 ms 13952 KB Output is correct
7 Correct 13 ms 13824 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 13 ms 13824 KB Output is correct
2 Correct 13 ms 13824 KB Output is correct
3 Correct 13 ms 13824 KB Output is correct
4 Correct 13 ms 13824 KB Output is correct
5 Correct 13 ms 13824 KB Output is correct
6 Correct 13 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 14 ms 14080 KB Output is correct
10 Correct 13 ms 14208 KB Output is correct
11 Correct 13 ms 14208 KB Output is correct
12 Correct 13 ms 14080 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 13 ms 13824 KB Output is correct
2 Correct 13 ms 13824 KB Output is correct
3 Correct 13 ms 13824 KB Output is correct
4 Correct 13 ms 13824 KB Output is correct
5 Correct 13 ms 13824 KB Output is correct
6 Correct 13 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 14 ms 14080 KB Output is correct
10 Correct 13 ms 14208 KB Output is correct
11 Correct 13 ms 14208 KB Output is correct
12 Correct 13 ms 14080 KB Output is correct
13 Correct 26 ms 19440 KB Output is correct
14 Correct 29 ms 19312 KB Output is correct
15 Correct 28 ms 19440 KB Output is correct
16 Correct 26 ms 19440 KB Output is correct
17 Correct 26 ms 19440 KB Output is correct
18 Correct 36 ms 19432 KB Output is correct
19 Correct 27 ms 19440 KB Output is correct
20 Correct 30 ms 19440 KB Output is correct
21 Correct 27 ms 19440 KB Output is correct
22 Correct 27 ms 19440 KB Output is correct
23 Correct 34 ms 19176 KB Output is correct
24 Correct 29 ms 19176 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 13 ms 13824 KB Output is correct
2 Correct 13 ms 13824 KB Output is correct
3 Correct 13 ms 13824 KB Output is correct
4 Correct 13 ms 13824 KB Output is correct
5 Correct 13 ms 13824 KB Output is correct
6 Correct 13 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 14 ms 14080 KB Output is correct
10 Correct 13 ms 14208 KB Output is correct
11 Correct 13 ms 14208 KB Output is correct
12 Correct 13 ms 14080 KB Output is correct
13 Correct 26 ms 19440 KB Output is correct
14 Correct 29 ms 19312 KB Output is correct
15 Correct 28 ms 19440 KB Output is correct
16 Correct 26 ms 19440 KB Output is correct
17 Correct 26 ms 19440 KB Output is correct
18 Correct 36 ms 19432 KB Output is correct
19 Correct 27 ms 19440 KB Output is correct
20 Correct 30 ms 19440 KB Output is correct
21 Correct 27 ms 19440 KB Output is correct
22 Correct 27 ms 19440 KB Output is correct
23 Correct 34 ms 19176 KB Output is correct
24 Correct 29 ms 19176 KB Output is correct
25 Correct 979 ms 157772 KB Output is correct
26 Correct 1162 ms 157528 KB Output is correct
27 Correct 936 ms 157436 KB Output is correct
28 Correct 907 ms 158088 KB Output is correct
29 Correct 1006 ms 157128 KB Output is correct
30 Correct 893 ms 157324 KB Output is correct
31 Correct 896 ms 157052 KB Output is correct
32 Correct 903 ms 156988 KB Output is correct
33 Correct 848 ms 150248 KB Output is correct
34 Correct 803 ms 150140 KB Output is correct
35 Correct 635 ms 150112 KB Output is correct
36 Execution timed out 2593 ms 436940 KB Time limit exceeded
37 Halted 0 ms 0 KB -