Cod sursa(job #1922021)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 10 martie 2017 15:44:29
Problema Nowhere-zero Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.48 kb
#include <fstream>
#include <algorithm>
#include <cmath>
#include <vector>

//8:33
using namespace std;

const int NMAX = 100000 + 5;
const int MMAX = 6 * NMAX;
const int FMAX = 2 * NMAX;

int N;
struct Point {
    double x, y;
} points[NMAX];

vector <int> graph[NMAX];

int edg;
struct Edge {
    int a, b;
    int nxt;
    int face;
    Edge(int _a = 0, int _b = 0, int _face = 0): a(_a), b(_b), face(_face) {}
} edges[MMAX];

int node;
bool cmp(const int &a, const int &b) {
    const Point &A = points[edges[a].b];
    const Point &B = points[edges[b].b];
    return atan2(A.y - points[node].y, A.x - points[node].x) < atan2(B.y - points[node].y, B.x - points[node].x);
}

int faces;
vector <int> facesGraph[FMAX];
int deg[FMAX];
bool out[FMAX];
int color[FMAX];

vector <pair <int, int> > facesGraphEdges;

int q[FMAX];
int st, dr;

int main()
{
    ifstream cin("nowhere-zero.in");
    ofstream cout("nowhere-zero.out");

    int M = 0;
    cin >> N >> M;

    for (int i = 1; i <= N; ++ i)
        cin >> points[i].x >> points[i].y;

    for (int i = 1; i <= M; ++ i) {
        int a, b;
        cin >> a >> b;

        edges[edg ++] = Edge(a, b);
        edges[edg ++] = Edge(b, a);
        graph[a].push_back(edg - 2);
        graph[b].push_back(edg - 1);
    }

    for (int i = 1; i <= N; ++ i) {
        node = i;
        sort(graph[i].begin(), graph[i].end(), cmp);

        for (int j = 0; j < graph[i].size(); ++ j) {
            int j2 = j + 1;
            if (j2 == graph[i].size())
                j2 = 0;
            edges[graph[i][j] ^ 1].nxt = graph[i][j2];
        }
    }

    for (int i = 0; i < edg; ++ i)
        if (!edges[i].face) {
            ++ faces;
            int node = i;
            do {
                edges[node].face = faces;
                node = edges[node].nxt;
            } while (!edges[node].face);
        }

    for (int i = 0; i < edg; i += 2) {
        int a = edges[i].face;
        int b = edges[i ^ 1].face;
        if (b < a)
            swap(a, b);
        facesGraphEdges.push_back(make_pair(a, b));
    }
    sort(facesGraphEdges.begin(), facesGraphEdges.end());
    facesGraphEdges.resize(unique(facesGraphEdges.begin(), facesGraphEdges.end()) - facesGraphEdges.begin());

    for (auto it: facesGraphEdges) {
        facesGraph[it.first].push_back(it.second);
        facesGraph[it.second].push_back(it.first);
        ++ deg[it.first], ++ deg[it.second];
    }

    st = 1;
    for (int i = 1; i <= faces; ++ i)
        if (deg[i] <= 5)
            q[++ dr] = i;

    while (st <= dr) {
        int node = q[st ++];
        out[node] = true;
        for (auto it: facesGraph[node])
            if (!out[it]) {
                -- deg[it];
                if (deg[it] == 5)
                    q[++ dr] = it;
            }
    }

    for (int i = faces; i; -- i) {
        int node = q[i];
        out[node] = false;

        bool freq[6] = {0};
        for (auto it: facesGraph[node])
            if (!out[it])
                freq[color[it]] = true;

        for (int i = 0; i < 6; ++ i)
            if (!freq[i]) {
                color[node] = i;
                break;
            }
    }


    for (int i = 0; i < edg; ++ i) {
        int a = edges[i].face;
        int b = edges[i ^ 1].face;

        if (color[a] - color[b] > 0)
            cout << edges[i].a << ' ' << edges[i].b << ' ' << color[a] - color[b] << '\n';
    }
    return 0;
}