Cod sursa(job #2236527)

Utilizator Alexa2001Alexa Tudose Alexa2001 Data 29 august 2018 20:22:13
Problema Nowhere-zero Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.33 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin ("nowhere-zero.in");
ofstream fout ("nowhere-zero.out");

const int Nmax = 3e5 + 5;

int n, m, i, x, y, Faces;
int color[Nmax], edge[Nmax], dgr[Nmax], P[Nmax];

vector< pair<double, int> > v[Nmax];
vector<int> inv[Nmax], face[Nmax], graph[Nmax];

bool used[Nmax], usedCol[7];

struct point
{
    double x, y;
} a[Nmax];

void read()
{
    int x, y, i;

    fin >> n >> m;
    for(i=1; i<=n; ++i) fin >> a[i].x >> a[i].y;

    for(i=1; i<=m; ++i)
    {
        fin >> x >> y;
        edge[i] = x^y;
        v[x].push_back({0, i});
        v[y].push_back({0, i});
    }
}

void detect_face(int node, int i)
{
    face[node][i] = Faces;
    int p = inv[node][i], x = v[node][i].second;
    ++p; p %= v[x].size();

    if(!face[x][p]) detect_face(x, p);
}

void build_graph()
{
    int node, i, id;

    for(node=1; node<=n; ++node)
    {
        for(auto &it : v[node])
        {
            id = node ^ edge[it.second];
            it.first = atan2(a[id].y - a[node].y, a[id].x - a[node].x);
        }

        sort(v[node].begin(), v[node].end());
        for(i=0; i<v[node].size(); ++i)
            P[v[node][i].second] ^= i;

        face[node].resize(v[node].size());
    }

    for(node=1; node<=n; ++node)
        for(i=0; i<v[node].size(); ++i)
        {
            inv[node].push_back(P[v[node][i].second] ^ i);
            v[node][i].second = node ^ edge[v[node][i].second];
        }

    for(node=1; node<=n; ++node)
        for(i=0; i<v[node].size(); ++i)
            if(!face[node][i])
            {
                ++Faces;
                detect_face(node, i);
            }

    for(node=1; node<=n; ++node)
        for(i=0; i<v[node].size(); ++i)
            if(node < v[node][i].second)
            {
                int x = face[node][i], y = face[v[node][i].second][inv[node][i]];
                if(!x || !y) continue;

                graph[x].push_back(y);
                graph[y].push_back(x);
            }
}

void color_graph()
{
    int i, n = Faces, node;
    priority_queue< pair<int,int> , vector< pair<int,int> > , greater< pair<int,int> > > heap;
    vector<int> ord;

    for(i=1; i<=n; ++i) dgr[i] = graph[i].size(), heap.push({ dgr[i], i });

    for(i=1; i<=n; ++i)
    {
        while(used[heap.top().second]) heap.pop();

        node = heap.top().second;
        used[node] = 1;
        ord.push_back(node);

        for(auto it : graph[node])
            heap.push( {--dgr[it], it} );
    }

    reverse(ord.begin(), ord.end());

    for(auto x : ord)
    {
        memset(usedCol, 0, sizeof(usedCol));
        for(auto it : graph[x]) usedCol[color[it]] = 1;

        for(i=1; !color[x] && i<=6; ++i)
            if(!usedCol[i]) color[x] = i;

        assert(color[x]);
    }
}

void print()
{
    int i, node, x, id1, id2;

    for(node = 1; node <= n; ++node)
        for(i=0; i<v[node].size(); ++i)
        {
            x = v[node][i].second;
            id1 = face[node][i];
            id2 = face[x][inv[node][i]];

            if(color[id1] > color[id2])
                fout << node << ' ' << x << ' ' << color[id1] - color[id2] << '\n';
        }
}

int main()
{
    read();
    build_graph();
    color_graph();
    print();

    return 0;
}