Cod sursa(job #1058113)

Utilizator poptibiPop Tiberiu poptibi Data 15 decembrie 2013 02:57:23
Problema Nowhere-zero Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.84 kb
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <set>
#include <unordered_set>
#include <unordered_map>
#include <vector>
#include <algorithm>
using namespace std;

const int NMAX = 100010, MMAX = 300010, FMAX = 200010;

int N, M, A, B, NrFaces, Deg[FMAX], VertexColor[FMAX], UsedColor[7];
double X[NMAX], Y[NMAX];
pair<int, int> Edges[MMAX], EdgeFaces[MMAX];
vector<pair<int, int> > G[NMAX];
vector<bool> Passed[NMAX];
unordered_set<int> FG[FMAX];
unordered_map<int, int> Idx[NMAX];
vector<int> ColoringOrder;
int Origin;
bool Used[NMAX];

struct Comp
{
    bool operator ()(const pair<int, int> &A, const pair<int, int> &B) const
    {
        return atan2(X[A.second] - X[Origin], Y[A.second] - Y[Origin]) < atan2(X[B.second] - X[Origin], Y[B.second] - Y[Origin]);
    }
};

void BuildFG()
{
    for(int i = 1; i <= N; ++ i)
    {
        Origin = i;
        sort(G[i].begin(), G[i].end(), Comp());
        Passed[i].resize(G[i].size());
        for(int j = 0; j < G[i].size(); ++ j)
            Idx[i][G[i][j].second] = j;
    }

    for(int i = 1; i <= N; ++ i)
        for(int j = 0; j < G[i].size(); ++ j)
            if(!Passed[i][j])
            {
                NrFaces ++;
                int Node = i, Pos = j;
                do
                {
                    Passed[Node][Pos] = 1;
                    int IdxEdge = G[Node][Pos].first, NextNode = G[Node][Pos].second;
                    if(EdgeFaces[IdxEdge].first == 0) EdgeFaces[IdxEdge].first = NrFaces, Edges[IdxEdge] = make_pair(Node, NextNode);
                    else EdgeFaces[IdxEdge].second = NrFaces;
                    Pos = (Idx[NextNode][Node] + 1) % G[NextNode].size();
                    Node = NextNode;
                }while(Node != i);
            }

    for(int i = 1; i <= M; ++ i)
    {
        FG[EdgeFaces[i].first].insert(EdgeFaces[i].second);
        FG[EdgeFaces[i].second].insert(EdgeFaces[i].first);
    }
}

void AssociateColors()
{
    set<pair<int, int> > DegSet;
    for(int i = 1; i <= NrFaces; ++ i)
    {
        Deg[i] = FG[i].size();
        DegSet.insert(make_pair(Deg[i], i));
    }

    while(!DegSet.empty())
    {
        int Node = DegSet.begin() -> second;
        DegSet.erase(DegSet.begin());
        if(Used[Node]) continue;
        Used[Node] = 1;
        ColoringOrder.push_back(Node);
        for(unordered_set<int> :: iterator it = FG[Node].begin(); it != FG[Node].end(); ++ it)
            if(!Used[*it])
            {
                Deg[*it] --;
                DegSet.insert(make_pair(Deg[*it], *it));
            }
    }

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

    for(int i = 0; i < ColoringOrder.size(); ++ i)
    {
        int Node = ColoringOrder[i];
        for(int i = 1; i <= 6; ++ i)
            UsedColor[i] = 0;
        for(unordered_set<int> :: iterator it = FG[Node].begin(); it != FG[Node].end(); ++ it)
            UsedColor[VertexColor[*it]] = 1;
        for(int i = 1; i <= 6; ++ i)
            if(!UsedColor[i])
            {
                VertexColor[Node] = i;
                break;
            }
    }
}

int main()
{
    freopen("nowhere-zero.in", "r", stdin);
    freopen("nowhere-zero.out", "w", stdout);

    scanf("%i %i", &N, &M);
    for(int i = 1; i <= N; ++ i) scanf("%lf %lf", &X[i], &Y[i]);
    for(int i = 1; i <= M; ++ i)
    {
        scanf("%i %i", &A, &B);
        G[A].push_back(make_pair(i, B));
        G[B].push_back(make_pair(i, A));
    }
    BuildFG();
    AssociateColors();
    for(int i = 1; i <= M; ++ i)
    {
        int Dif = VertexColor[EdgeFaces[i].first] - VertexColor[EdgeFaces[i].second];
        if(Dif < 0) printf("%i %i %i\n", Edges[i].first, Edges[i].second, -Dif);
        else printf("%i %i %i\n", Edges[i].second, Edges[i].first, Dif);
    }
}