Pagini recente » Cod sursa (job #25494) | Cod sursa (job #2164618) | Cod sursa (job #75142) | Cod sursa (job #557241) | Cod sursa (job #2703023)
#ifdef LOCAL
#include <debug.hpp>
#else
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,tune=native")
#define debug(...)
#endif
#include <bits/stdc++.h>
using namespace std;
using Point = complex<double>;
int half(Point p) { return p.imag() < 0 || (p.imag() == 0 && p.real() < 0); }
double cross(Point p, Point q) { return p.real() * q.imag() - p.imag() * q.real(); }
struct Edge { int origin, nxt, face; };
vector<int> ComputeList(vector<Point>& P, vector<array<int, 2>>& E) {
int n = P.size(), m = E.size();
vector<int> ord(m);
iota(ord.begin(), ord.end(), 0);
sort(ord.begin(), ord.end(), [&](int a, int b) {
if (E[a][0] != E[a][1]) return E[a][0] < E[a][1];
Point p = P[E[a][1]] - P[E[a][0]],
q = P[E[b][1]] - P[E[b][0]];
if (half(p) != half(q)) return half(p) < half(q);
return cross(p, q) > 0;
});
int l = 0, r = 0;
vector<int> nxt(m);
for (l = 0; l < m; l = r) {
for (r = l + 1; r < m && E[ord[r]][0] == E[ord[l]][0]; ++r)
nxt[ord[r - 1]] = ord[r];
nxt[ord[r - 1]] = ord[l];
}
for (int i = 0; i < m; i += 2) swap(nxt[i], nxt[i ^ 1]);
return nxt;
}
int main() {
ifstream cin("nowhere-zero.in");
ofstream cout("nowhere-zero.out");
int n, m; cin >> n >> m;
vector<Point> P(n);
for (int i = 0; i < n; ++i) {
double x, y; cin >> x >> y;
P[i] = {x, y};
}
vector<array<int, 2>> E;
for (int i = 0; i < m; ++i) {
int a, b; cin >> a >> b; --a; --b;
E.push_back({a, b});
E.push_back({b, a});
}
m *= 2;
auto nxt = ComputeList(P, E);
int f = 0;
vector<int> which(m, -1);
for (int i = 0; i < m; ++i) {
if (which[i] != -1) continue;
for (int j = i; which[j] == -1; j = nxt[j])
which[j] = f;
++f;
}
vector<vector<int>> dual(f);
for (int i = 0; i < m; ++i)
dual[which[i]].push_back(which[i ^ 1]);
vector<int> deg(f, 0);
for (int i = 0; i < f; ++i) {
sort(dual[i].begin(), dual[i].end());
dual[i].erase(unique(dual[i].begin(), dual[i].end()), dual[i].end());
deg[i] = dual[i].size();
}
vector<int> q;
for (int i = 0; i < f; ++i)
if (deg[i] <= 5)
q.push_back(i);
for (int i = 0; i < f; ++i) {
int node = q[i];
for (auto vec : dual[node]) {
if (--deg[vec] == 5)
q.push_back(vec);
}
}
reverse(q.begin(), q.end());
vector<int> col(f, -1);
for (auto node : q) {
int bad = 0;
for (auto vec : dual[node]) {
if (col[vec] != -1)
bad |= (1 << col[vec]);
}
col[node] = 0;
while (bad & (1 << col[node]))
++col[node];
}
for (int i = 0; i < m; ++i) {
int df = col[which[i]] - col[which[i ^ 1]];
if (df > 0)
cout << E[i][0] + 1 << " " << E[i][1] + 1 << " " << df << '\n';
}
return 0;
}