Pagini recente » Cod sursa (job #1095489) | Cod sursa (job #380486) | Cod sursa (job #2587972) | Cod sursa (job #1167623) | Cod sursa (job #1928989)
#include <fstream>
#include <vector>
#include <cstring>
#include <algorithm>
#include <set>
#include <bitset>
#include <queue>
const int kMaxVertices = 100010;
const int kMaxEdges = 600010;
const int kMaxFaces = 300010;
struct Point {
Point (double _x = 0, double _y = 0) :
x(_x),
y(_y) {
}
double x, y;
};
struct Edge {
Edge (int _first = 0, int _second = 0, int _nextOnFace = 0, int _face = 0) :
first(_first),
second(_second),
nextOnFace(_nextOnFace),
face(_face) {
}
int first, second;
int nextOnFace, face;
};
int vertexCount;
Point vertices[kMaxVertices];
int edgeCount;
Edge edges[kMaxEdges];
std::vector< int > adjEdges[kMaxVertices];
int faceCount;
std::vector< int > faceGraph[kMaxFaces];
std::set< std::pair<int, int> > faceEdges;
int faceGraphDegrees[kMaxFaces], color[kMaxFaces];
inline int RevEdge(const int& edge) {
return (edge ^ 1);
}
inline void ComputeNextOnFaceForAllEdges() {
for (int i = 1; i <= vertexCount; ++i) {
Point& vertex = vertices[i];
std::sort(adjEdges[i].begin(), adjEdges[i].end(),
[&](const int& a, const int& b) {
Point& first = vertices[edges[a].second];
Point& second = vertices[edges[b].second];
return atan2(first.y - vertex.y, first.x - vertex.x)
< atan2(second.y - vertex.y, second.x - vertex.x);
});
for (int curr = 0; curr < (int)adjEdges[i].size(); ++curr) {
int next = curr + 1;
if (next == (int)adjEdges[i].size())
next = 0;
edges[RevEdge(adjEdges[i][next])].nextOnFace = adjEdges[i][curr];
}
}
}
inline void ComputeFaces() {
for (int i = 0; i < edgeCount; ++i) {
if (edges[i].face != 0)
continue;
edges[i].face = ++faceCount;
for (int edge = edges[i].nextOnFace; edge != i; edge = edges[edge].nextOnFace)
edges[edge].face = faceCount;
}
}
inline void ComputeFaceGraph() {
for (int i = 0; i < edgeCount; i += 2) {
int first = edges[i].face;
int second = edges[i + 1].face;
faceEdges.insert(std::make_pair( std::min(first, second), std::max(first, second) ));
}
for (std::pair<int, int> edge : faceEdges) {
faceGraph[edge.first].push_back(edge.second);
faceGraphDegrees[edge.first]++;
faceGraph[edge.second].push_back(edge.first);
faceGraphDegrees[edge.second]++;
}
}
inline void ColorFaceGraph() {
std::queue< int > que;
std::vector< int > orderedFaces;
for (int i = 1; i <= faceCount; ++i) {
if (faceGraphDegrees[i] > 5)
continue;
que.push(i);
orderedFaces.push_back(i);
}
while (!que.empty()) {
int face = que.front();
que.pop();
for (int adj : faceGraph[face]) {
faceGraphDegrees[adj]--;
if (faceGraphDegrees[adj] == 5) {
que.push(adj);
orderedFaces.push_back(adj);
}
}
}
std::reverse(orderedFaces.begin(), orderedFaces.end());
std::bitset< kMaxFaces > fixed; fixed.reset();
std::bitset< 10 > appeared;
for (int face : orderedFaces) {
fixed[face] = true;
appeared.reset();
for (int adj : faceGraph[face])
if (fixed[adj])
appeared[ color[adj] ] = true;
for (int i = 1; i <= 6; ++i) {
if (appeared[i])
continue;
color[face] = i;
break;
}
}
}
int main() {
std::ifstream inputFile("nowhere-zero.in");
std::ofstream outputFile("nowhere-zero.out");
inputFile >> vertexCount >> edgeCount;
for (int i = 1; i <= vertexCount; ++i)
inputFile >> vertices[i].x >> vertices[i].y;
int cnt = 0;
for (int i = 1; i <= edgeCount; ++i) {
int first, second;
inputFile >> first >> second;
edges[cnt++] = Edge(first, second);
adjEdges[first].push_back(cnt - 1);
edges[cnt++] = Edge(second, first);
adjEdges[second].push_back(cnt - 1);
}
edgeCount = cnt;
ComputeNextOnFaceForAllEdges();
ComputeFaces();
ComputeFaceGraph();
ColorFaceGraph();
for (int i = 0; i < edgeCount; ++i) {
int first = edges[i].face;
int second = edges[RevEdge(i)].face;
if (color[first] < color[second])
continue;
outputFile << edges[i].first << ' ' << edges[i].second << ' ' << color[first] - color[second] << '\n';
}
inputFile.close();
outputFile.close();
return 0;
}
//Trust me, I'm the Doctor!