Cod sursa(job #1245963)

Utilizator geniucosOncescu Costin geniucos Data 20 octombrie 2014 12:04:03
Problema Nowhere-zero Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.1 kb
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>

using namespace std;

int Nr, n, m, st[600009], dr[600009], poligon[600009], nxt[600009], Ap[600009], culoare[600009], grad[600009];

double X[100009], Y[100009];

priority_queue < pair < int , int > > PQ;
vector < int > muchii[100009], v[600009], order;
vector < pair < double, int > > vec;

double Det_Unghi(double x, double y)
{
    double result = (double)atan2 (y,x) * 180 / M_PI + 90;
    if (result < 0) result = 360 + result;
    return result;
}

int Get_color (int nod)
{
    int mp = 0;
    for (vector < int > :: iterator it = v[nod].begin(); it != v[nod].end(); it++)
        if (Ap[*it]) mp |= 1<<culoare[*it];
    for (int i=1; i<=7; i++)
        if ( (mp & (1<<i)) == 0)
            return i;
}

int rev (int i)
{
    if (i<=m) return i+m;
    return i-m;
}

int main()
{
freopen ("nowhere-zero.in", "r", stdin);
freopen ("nowhere-zero.out", "w", stdout);
scanf ("%d %d", &n, &m);

for (int i=1; i<=n; i++)
    scanf ("%lf %lf", &X[i], &Y[i]);

for (int i=1; i<=m; i++)
{
    scanf ("%d %d", &st[i], &dr[i]);
    dr[i+m] = st[i];
    st[i+m] = dr[i];
}

for (int i=1; i<=2*m; i++)
    muchii[st[i]].push_back(i);

for (int i=1; i<=n; i++)
{
    vec.clear();
    for (vector < int > :: iterator it = muchii[i].begin(); it != muchii[i].end(); it++)
        vec.push_back ( make_pair ( (double)Det_Unghi ( (double)X[dr[*it]] - X[i], (double)Y[dr[*it]] - Y[i] ) , *it) ) ;
    sort (vec.begin(), vec.end());
    for (int j = 0; j < vec.size(); j++)
        nxt [rev(vec[j].second)] = vec[(j+1)%vec.size()].second;
}

for (int i=1; i<=2*m; i++)
    if (poligon[i] == 0)
    {
        int j = i;
        poligon[i] = ++Nr;
        while (1)
        {
            j = nxt[j];
            if (poligon[j] != 0) break;
            poligon[j] = Nr;
        }
    }

for (int i=1; i<=m; i++)
    if (poligon[i] != poligon[m+i])
    {
        v[poligon[i]].push_back(poligon[m+i]);
        v[poligon[m+i]].push_back(poligon[i]);
        grad[poligon[i]] ++;
        grad[poligon[i+m]] ++;
    }

for (int i=1; i<=Nr; i++)
    PQ.push(make_pair(grad[i], i));

while (1)
{
    pair < int , int > tp;
    while (1)
    {
        if (PQ.empty()) break;
        tp = PQ.top();
        if (grad[tp.second] == tp.first && !Ap[tp.second]) break;
        PQ.pop();
    }
    if (PQ.empty()) break;
    PQ.pop();
    order.push_back(tp.second);
    Ap[tp.second] = 1;
    for (vector < int > :: iterator it = v[tp.second].begin(); it != v[tp.second].end(); it++)
        if (Ap[*it] == 0)
        {
            grad[*it] --;
            PQ.push(make_pair(grad[*it], *it));
        }
}

reverse(order.begin(), order.end());
for (int i=1; i<=Nr; i++)
    Ap[i] = 0;
for (vector < int > :: iterator it = order.begin(); it != order.end(); it++)
{
    Ap[*it] = 1;
    culoare[*it] = Get_color(*it);
}

for (int i=1; i<=2*m; i++)
    if (culoare[poligon[i]] < culoare[poligon[rev(i)]])
        printf ("%d %d %d\n", st[i], dr[i], culoare[poligon[rev(i)]] - culoare[poligon[i]]);

return 0;
}