Cod sursa(job #1245947)

Utilizator geniucosOncescu Costin geniucos Data 20 octombrie 2014 11:47:20
Problema Nowhere-zero Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.95 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];
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;
}

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

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));

calc_culoare();

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;
}