Pagini recente » Cod sursa (job #2197627) | Cod sursa (job #318515) | Cod sursa (job #2500806) | Istoria paginii runda/532 | Cod sursa (job #1168787)
#include <cassert>
#include <cmath>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
const int MAX_N = 100005;
const double INFINITE = 1.e9;
struct PointXY {
double x, y;
} point[MAX_N];
pair<int, int> edge[MAX_N * 6];
vector< pair<double, int> > graph[MAX_N];
vector<int> aib[MAX_N];
vector<int> face_graph[MAX_N * 3];
map< pair<int, int>, int > index;
int face[MAX_N * 6];
int color[MAX_N * 3];
bool vis[MAX_N * 3];
int deg[MAX_N * 3];
inline double angle(int u, int v) {
return atan2(point[v].y - point[u].y, point[v].x - point[u].x);
}
void build_face(int current, int face_index) {
int start = edge[current].first;
//cout << "Face #" << face_index << "\n";
while(edge[current].second != start) {
//cout << current << "\n";
face[current] = face_index;
double enter = angle(edge[current].second, edge[current].first);
int node = edge[current].second;
int pos = upper_bound(graph[node].begin(), graph[node].end(), make_pair(enter, 0)) - graph[node].begin();
for(pos = pos + 1; aib[node][pos] == 0; ++ pos);
aib[node][pos] = 0;
current = index[make_pair(node, graph[node][pos].second)];
}
face[current] = face_index;
}
inline int get_color(int node) {
int f[7] = {0};
for(vector<int> :: iterator it = face_graph[node].begin(); it != face_graph[node].end(); ++ it) {
f[color[*it]] = 1;
}
for(int i = 1; i < 7; ++ i) {
if(!f[i]) {
return i;
}
}
return 0;
}
void color_faces(int n) {
vector<int> order;
int first = 0;
for(int i = 1; i <= n; ++ i) {
deg[i] = static_cast<int>(face_graph[i].size());
if(deg[i] < 6) {
order.push_back(i);
vis[i] = true;
}
}
while(first < static_cast<int>(order.size())) {
int node = order[first];
++ first;
for(vector<int> :: iterator it = face_graph[node].begin(); it != face_graph[node].end(); ++ it) {
-- deg[*it];
if(deg[*it] < 6 && !vis[*it]) {
order.push_back(*it);
vis[*it] = true;
}
}
}
for(int i = n - 1; i >= 0; -- i) {
color[i] = get_color(i);
}
}
int main() {
ifstream fin("nowhere-zero.in");
ofstream fout("nowhere-zero.out");
int n, m;
fin >> n >> m;
for(int i = 1; i <= n; ++ i) {
fin >> point[i].x >> point[i].y;
graph[i].push_back(make_pair(-INFINITE, 0));
aib[i].push_back(0);
}
for(int i = 1; i <= m; ++ i) {
int x, y;
fin >> x >> y;
graph[x].push_back(make_pair(angle(x, y), y));
graph[y].push_back(make_pair(angle(y, x), x));
edge[i] = make_pair(x, y);
edge[i + m] = make_pair(y, x);
index[edge[i]] = i;
index[edge[i + m]] = i + m;
}
for(int i = 1; i <= n; ++ i) {
sort(graph[i].begin(), graph[i].end());
int deg = static_cast<int>(graph[i].size()) - 1;
for(int j = 1; j <= 2 * deg; ++ j) {
aib[i].push_back(1); //o sa schimb mai incolo in aib-uri pe bune
}
for(int j = 1; j <= deg; ++ j) {
graph[i].push_back(make_pair(graph[i][j].first + 2 * M_PI, graph[i][j].second));
}
}
int faces = 0;
for(int i = 1; i <= 2 * m; ++ i) {
if(!face[i]) {
build_face(i, ++ faces);
}
//fout << edge[i].first << " " << edge[i].second << " " << face[i] << "\n";
}
for(int i = 1; i <= m; ++ i) {
if(face[i] != face[m + i]) {
face_graph[face[i]].push_back(face[m + i]);
face_graph[face[m + i]].push_back(face[i]);
}
}
color_faces(faces);
for(int i = 1; i <= m; ++ i) {
if(color[face[i]] < color[face[i + m]]) {
fout << edge[i].second << " " << edge[i].first << " " << color[face[i + m]] - color[face[i]] << "\n";
} else {
assert(color[face[i]] != color[face[i + m]]);
fout << edge[i].first << " " << edge[i].second << " " << color[face[i]] - color[face[i + m]] << "\n";
}
}
return 0;
}