Cod sursa(job #1935187)

Utilizator RazvanR104Razvan-Andrei Ciocoiu RazvanR104 Data 22 martie 2017 04:26:55
Problema Nowhere-zero Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.12 kb
#include <bits/stdc++.h>

using namespace std;

typedef long double ld;
const int NMAX = 100010;
const ld eps = 1e-3;

int N, M;
int refPoint;
int pairEdge[6 * NMAX], faceEdge[6 * NMAX], deg[6 * NMAX], colorFace[6 * NMAX];
bool inQueue[6 * NMAX];
vector<int> G[NMAX], faceG[6 * NMAX];
struct Edge {
	int x, y;
} E[6 * NMAX];
struct Point {
	ld x, y;
} P[NMAX];

int getSign(const ld &value) {
	if (value < -eps)
		return -1;
	if (value > eps)
		return 1;
	return 0;
}
int crossProduct(const Point &A, const Point &B, const Point &C) {
	ld value = A.x * (B.y - C.y) + B.x * (C.y - A.y) + C.x * (A.y - B.y);
	return getSign(value);
}
struct Compare {
	bool operator()(const int &lhs, const int &rhs) const {
		//return crossProduct(P[refPoint], P[E[lhs].y], P[E[rhs].y]) > 0;
		return atan2(P[E[lhs].y].y - P[refPoint].y, P[E[lhs].y].x - P[refPoint].x) > atan2(P[E[rhs].y].y - P[refPoint].y, P[E[rhs].y].x - P[refPoint].x);
	}
};

int main() {
	assert(freopen("nowhere-zero.in", "r", stdin));
	assert(freopen("nowhere-zero.out", "w", stdout));
	int i, j;
	cin >> N >> M;
	for (i = 1; i <= N; ++i)
		cin >> P[i].x >> P[i].y;
	for (i = 0; i < M; ++i) {
		int x, y;
		cin >> x >> y;
		E[i * 2] = {x, y};
		E[i * 2 + 1] = {y, x};
		G[x].push_back(i * 2);
		G[y].push_back(i * 2 + 1);
	}
	for (i = 1; i <= N; ++i) {
		refPoint = i;
		sort(G[i].begin(), G[i].end(), Compare());
		for (j = 0; j < int(G[i].size()); ++j) {
			int next = (j + 1) < int(G[i].size()) ? (j + 1) : 0;
			pairEdge[G[i][j]] = G[i][next] ^ 1;
		}
	}
	int currFace = 1;
	for (i = 0; i < 2 * M; ++i) {
		if (faceEdge[i])
			continue;
		int currEdge = i;
		do {
			faceEdge[currEdge] = currFace;
			currEdge = pairEdge[currEdge];
		} while (!faceEdge[currEdge]);
		++currFace;
	}
	vector<pair<int, int>> faceGraphEdges;
	for (i = 0; i < M; ++i) {
		int x = faceEdge[2 * i], y = faceEdge[2 * i + 1];
		if (x > y)
			swap(x, y);
		faceGraphEdges.push_back({x, y});
	}
	sort(faceGraphEdges.begin(), faceGraphEdges.end());
	faceGraphEdges.erase(unique(faceGraphEdges.begin(), faceGraphEdges.end()), faceGraphEdges.end());
	for (const auto &it: faceGraphEdges) {
		faceG[it.first].push_back(it.second);
		faceG[it.second].push_back(it.first);
		++deg[it.first];
		++deg[it.second];
	}
	vector<int> Q;
	int left = 0, right = -1;
	for (i = 1; i < currFace; ++i)
		if (deg[i] <= 5) {
			Q.push_back(i);
			inQueue[i] = 1;
			++right;
		}
	while (left <= right) {
		int now = Q[left++];
		for (const int &it: faceG[now]) {
			if (inQueue[it])
				continue;
			--deg[it];
			if (deg[it] == 5) {
				Q.push_back(it);
				++right;
				inQueue[it] = 1;
			}
		}
	}
	for (i = int(Q.size()) - 1; i >= 0; --i) {
		bool color[7] = {};
		for (const int &next: faceG[Q[i]])
				color[colorFace[next]] = 1;
		for (j = 1; j < 7; ++j)
			if (!color[j]) {
				colorFace[Q[i]] = j;
				break;
			}
	}
	for (i = 0; i < 2 * M; ++i) {
		if (colorFace[faceEdge[i]] - colorFace[faceEdge[i ^ 1]] <= 0)
			continue;
		cout << E[i].x << ' ' << E[i].y << ' ' << colorFace[faceEdge[i]] - colorFace[faceEdge[i ^ 1]] << '\n';
	}

	return 0;
}