답안 #227053

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
227053 2020-04-25T23:24:15 Z abeker Matching (COCI20_matching) C++17
58 / 110
1054 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;
const int MAXV = 1e7 + 5;

struct Node {
	int val;
	Node* nxt;
};

class Graph {
	Node* get_node(int dest, Node* head) {
		Node* newNode = new Node;
		newNode -> val = dest;
		newNode -> nxt = head;
		return newNode;
	}
	int N;
	public:
		Node **head;
		Graph(int N) {
			head = new Node*[N]();
			this -> N = N;
			for (int i = 0; i < N; i++)
				head[i] = nullptr;
		}
		void add(int src, int dest) {
			head[src] = get_node(dest, head[src]);
		}
		~Graph() {
			for (int i = 0; i < N; i++)
				delete[] head[i];
			delete[] head;
		}
};

int n;
bool sol[MAXV];
char bio[MAXV];
stack <int> order;
Graph adj(MAXV), rev(MAXV);

inline int add_variables(int vars) {
	n += vars;
	assert(2 * n < MAXV);
	return n - vars;
}

void add_edge(int u, int v) {
	adj.add(u, v);
	rev.add(v, 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 dfs_forward(int x) {
	bio[x] = 1;
	for (Node* ptr = adj.head[x]; ptr != nullptr; ptr = ptr -> nxt)
		if (!bio[ptr -> val])
			dfs_forward(ptr -> val);
	order.push(x);
}

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

void dfs_backward(int x) {
	if (bio[x ^ 1] == -1)
		bye();
	bio[x] = -1;
	sol[x] = bio[x ^ 1];
	for (Node* ptr = rev.head[x]; ptr != nullptr; ptr = ptr -> nxt)
		if (!bio[ptr -> val])
			dfs_backward(ptr -> val);
	bio[x] = 1;
}

void two_sat() {
	for (int i = 0; i < 2 * n; i++)
		if (!bio[i])
			dfs_forward(i);
	for (int i = 0; i < 2 * n; i++)
		bio[i] = 0;
	for (; !order.empty(); order.pop())
		if (!bio[order.top()])
			dfs_backward(order.top());
}

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> graph[MAXN];
 
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);
}
 
inline int get_id(int node, int x) {
	return x < off[node] ? st[node] + x : tour[node][x - off[node]].second;
}
 
void add_clause(int x, int u, int v) {
	if (u < off[x] + tour[x].size())
		add_implication(get_id(x, u), 0, get_id(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] = 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) {
	int lo = 0, hi = tour[x].size();
	while (lo < hi) {
		int mid = (lo + hi) / 2;
		if (tour[x][mid].first >= val)
			hi = mid;
		else
			lo = mid + 1;
	}
	return lo;
}
 
void update(int node, int from, int to, int var) {
	from += off[node];
	to += off[node];
	while (from < to) {
		if (from % 2) 
			add_implication(get_id(node, from++), 0, var, 1);
		if (to % 2) 
			add_implication(get_id(node, --to), 0, var, 1);
		from /= 2;
		to /= 2;
	}
}
 
void add_intersections(int x, int down, int up, int var) {
	for (x += offset; x; x /= 2) 
		if (off[x])
			update(x, get_bounds(x, down), get_bounds(x, up + 1), var);
}
 
void solve() {
	for (int i = 1; i < MAXN; i++) 
		if (hor[i].size() == 2) {
			int tmp = add_variables(1);
			segs[tmp] = {hor[i][0], hor[i][1]};
			int l = MAXN, r = 0;
			for (auto it : hor[i]) {
				graph[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 = add_variables(1);
			segs[tmp] = {ver[i][0], ver[i][1]};
			int l = MAXN, r = 0;
			for (auto it : ver[i]) {
				graph[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 (!graph[i].empty())
			add_implication(graph[i][0], 1, graph[i][1 % graph[i].size()], 0);
		else
			bye();
	
	two_sat();
	
	puts("DA");
	for (auto it : segs)
		if (sol[2 * it.first])
			printf("%d %d\n", it.second.first + 1, it.second.second + 1);
}
 
int main() {
	double timer = clock();
	load();
	solve();
	fprintf(stderr, "%lf\n", (clock() - timer) / CLOCKS_PER_SEC);
	return 0;
}

Compilation message

matching.cpp: In function 'void add_clause(int, int, int)':
matching.cpp:132: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:141: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:107:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d", &N);
  ~~~~~^~~~~~~~~~
matching.cpp:109: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 123 ms 170488 KB Output is correct
2 Correct 144 ms 170488 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 123 ms 170488 KB Output is correct
2 Correct 144 ms 170488 KB Output is correct
3 Correct 120 ms 170360 KB Output is correct
4 Correct 124 ms 170368 KB Output is correct
5 Correct 123 ms 170488 KB Output is correct
6 Correct 121 ms 170592 KB Output is correct
7 Correct 141 ms 170360 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 123 ms 170488 KB Output is correct
2 Correct 144 ms 170488 KB Output is correct
3 Correct 120 ms 170360 KB Output is correct
4 Correct 124 ms 170368 KB Output is correct
5 Correct 123 ms 170488 KB Output is correct
6 Correct 121 ms 170592 KB Output is correct
7 Correct 141 ms 170360 KB Output is correct
8 Correct 131 ms 170688 KB Output is correct
9 Correct 125 ms 170664 KB Output is correct
10 Correct 124 ms 170852 KB Output is correct
11 Correct 123 ms 170872 KB Output is correct
12 Correct 140 ms 170720 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 123 ms 170488 KB Output is correct
2 Correct 144 ms 170488 KB Output is correct
3 Correct 120 ms 170360 KB Output is correct
4 Correct 124 ms 170368 KB Output is correct
5 Correct 123 ms 170488 KB Output is correct
6 Correct 121 ms 170592 KB Output is correct
7 Correct 141 ms 170360 KB Output is correct
8 Correct 131 ms 170688 KB Output is correct
9 Correct 125 ms 170664 KB Output is correct
10 Correct 124 ms 170852 KB Output is correct
11 Correct 123 ms 170872 KB Output is correct
12 Correct 140 ms 170720 KB Output is correct
13 Correct 133 ms 174712 KB Output is correct
14 Correct 132 ms 174840 KB Output is correct
15 Correct 157 ms 174688 KB Output is correct
16 Correct 134 ms 174712 KB Output is correct
17 Correct 144 ms 174840 KB Output is correct
18 Correct 132 ms 174840 KB Output is correct
19 Correct 134 ms 174688 KB Output is correct
20 Correct 132 ms 174712 KB Output is correct
21 Correct 136 ms 174712 KB Output is correct
22 Correct 155 ms 174712 KB Output is correct
23 Correct 135 ms 175096 KB Output is correct
24 Correct 159 ms 175096 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 123 ms 170488 KB Output is correct
2 Correct 144 ms 170488 KB Output is correct
3 Correct 120 ms 170360 KB Output is correct
4 Correct 124 ms 170368 KB Output is correct
5 Correct 123 ms 170488 KB Output is correct
6 Correct 121 ms 170592 KB Output is correct
7 Correct 141 ms 170360 KB Output is correct
8 Correct 131 ms 170688 KB Output is correct
9 Correct 125 ms 170664 KB Output is correct
10 Correct 124 ms 170852 KB Output is correct
11 Correct 123 ms 170872 KB Output is correct
12 Correct 140 ms 170720 KB Output is correct
13 Correct 133 ms 174712 KB Output is correct
14 Correct 132 ms 174840 KB Output is correct
15 Correct 157 ms 174688 KB Output is correct
16 Correct 134 ms 174712 KB Output is correct
17 Correct 144 ms 174840 KB Output is correct
18 Correct 132 ms 174840 KB Output is correct
19 Correct 134 ms 174688 KB Output is correct
20 Correct 132 ms 174712 KB Output is correct
21 Correct 136 ms 174712 KB Output is correct
22 Correct 155 ms 174712 KB Output is correct
23 Correct 135 ms 175096 KB Output is correct
24 Correct 159 ms 175096 KB Output is correct
25 Correct 855 ms 302732 KB Output is correct
26 Correct 853 ms 302444 KB Output is correct
27 Correct 858 ms 302524 KB Output is correct
28 Correct 1054 ms 302788 KB Output is correct
29 Correct 792 ms 302344 KB Output is correct
30 Correct 821 ms 302432 KB Output is correct
31 Correct 823 ms 302400 KB Output is correct
32 Correct 797 ms 302216 KB Output is correct
33 Correct 762 ms 289600 KB Output is correct
34 Correct 713 ms 289672 KB Output is correct
35 Correct 557 ms 277640 KB Output is correct
36 Runtime error 879 ms 524292 KB Execution killed with signal 9 (could be triggered by violating memory limits)
37 Halted 0 ms 0 KB -