Pagini recente » Cod sursa (job #454038) | Mihnea Andreescu | Rating patrichi stefan (steverino123) | Cod sursa (job #141776) | Cod sursa (job #962789)
Cod sursa(job #962789)
#include <cstdio>
#include <cmath>
#include <cassert>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#define x first
#define y second
using namespace std;
typedef pair<double, double> Point;
typedef pair<int, int> Edge;
const int MAX_COLOR = 7;
vector<Point> Points;
vector<double> Alpha;
vector<vector<int>> G, RegionG;
int V, E, R;
vector<Edge> Edges;
vector<int> Next, RegionIndex, Colors;
vector<vector<int>> Regions;
inline int ReverseIndex(const int index) {
if (index < E)
return index + E;
return index - E;
}
void BuildGraph() {
Next.resize(2 * E);
for (int x = 0; x < V; ++x) {
for (auto &e: G[x])
Alpha[e] = atan2(Points[Edges[e].y].y - Points[x].y, Points[Edges[e].y].x - Points[x].x);
sort(G[x].begin(), G[x].end(), [](const int &e1, const int &e2) -> bool {
return Alpha[e1] < Alpha[e2];
});
for (int i = 0; i < static_cast<int>(G[x].size()); ++i)
Next[G[x][i]] = ReverseIndex(G[x][(i + 1) % static_cast<int>(G[x].size())]);
}
}
void BuildRegions() {
RegionIndex.resize(2 * E);
vector<bool> usedEdges = vector<bool>(2 * E, false);
for (int x = 0; x < V; ++x) {
for (auto e: G[x]) {
vector<int> region;
for (; !usedEdges[e]; e = Next[e]) {
region.push_back(e);
RegionIndex[e] = static_cast<int>(Regions.size());
usedEdges[e] = true;
}
if (!region.empty())
Regions.push_back(region);
}
}
R = static_cast<int>(Regions.size());
RegionG.resize(R);
Colors.resize(R);
}
void BuildRegionGraph() {
for (int i = 0; i < E; ++i) {
int x = RegionIndex[i], u = RegionIndex[ReverseIndex(i)];
RegionG[x].push_back(u); RegionG[u].push_back(x);
}
for (int x = 0; x < R; ++x) {
sort(RegionG[x].begin(), RegionG[x].end());
RegionG[x].erase(unique(RegionG[x].begin(), RegionG[x].end()), RegionG[x].end());
}
}
inline int GetColor(const int x) {
vector<bool> used = vector<bool>(MAX_COLOR, false);
for (auto &y: RegionG[x])
used[Colors[y]] = true;
for (int color = 1; color < MAX_COLOR; ++color)
if (!used[color])
return color;
return 0;
}
void ColorRegions() {
vector<int> degrees = vector<int>(R, 0);
for (int x = 0; x < R; ++x)
degrees[x] = static_cast<int>(RegionG[x].size());
stack<int> order;
queue<int> q;
vector<bool> used = vector<bool>(R, false);
for (int x = 0; x < R; ++x) {
if (degrees[x] < MAX_COLOR - 1) {
q.push(x);
used[x] = true;
}
}
for (; !q.empty(); q.pop()) {
int x = q.front();
order.push(x);
for (auto &y: RegionG[x]) {
--degrees[y];
if (degrees[y] < MAX_COLOR - 1 && !used[y]) {
q.push(y);
used[y] = true;
}
}
}
for (int x = 0; x < R; ++x)
Colors[x] = 0;
for (; !order.empty(); order.pop()) {
int x = order.top();
Colors[x] = GetColor(x);
}
}
void Solve() {
BuildGraph();
BuildRegions();
BuildRegionGraph();
ColorRegions();
}
void Read() {
assert(freopen("nowhere-zero.in", "r", stdin));
assert(scanf("%d %d", &V, &E) == 2);
G.resize(V);
Points.resize(V);
Alpha.resize(2 * E);
Edges.resize(2 * E);
for (int i = 0; i < V; ++i)
assert(scanf("%lf %lf", &Points[i].x, &Points[i].y) == 2);
for (int i = 0; i < E; ++i) {
int x, y; assert(scanf("%d %d", &x, &y) == 2);
--x; --y;
Edges[i] = Edge(x, y);
Edges[ReverseIndex(i)] = Edge(y, x);
G[x].push_back(i); G[y].push_back(ReverseIndex(i));
}
}
void Print() {
assert(freopen("nowhere-zero.out", "w", stdout));
for (int i = 0; i < 2 * E; ++i) {
int flow = Colors[RegionIndex[i]] - Colors[RegionIndex[ReverseIndex(i)]];
if (flow < 0)
continue;
printf("%d %d %d\n", Edges[i].x + 1, Edges[i].y + 1, flow);
}
}
int main() {
Read();
Solve();
Print();
return 0;
}