Cod sursa(job #1747829)

Utilizator laurageorgescuLaura Georgescu laurageorgescu Data 25 august 2016 17:33:26
Problema Nowhere-zero Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.03 kb
#include<cstdio>
#include<cmath>
#include<utility>
#include<vector>
#include<algorithm>
#include<set>

using namespace std;

FILE *fin = fopen( "nowhere-zero.in", "r" ), *fout = fopen( "nowhere-zero.out", "w" );

typedef vector< int > graf;

struct Pct{
    double x, y;
};
struct Muchie{
    int x, y;

    inline int capat( int a ) {
        return (x + y) - a;
    }
};
struct str{
    int nod, grad;

    str() {}
    str( int _nod, int _grad ) { nod = _nod, grad = _grad; }

    inline bool operator < (const str &a) const {
        if (grad != a.grad) return (grad < a.grad);
        return (nod < a.nod);
    }
}; set< str > s;

const int nmax = 1e5;
const int mmax = 3 * nmax;
const int cmax = 6;

int n, m, c;
Pct v[nmax + 1];

int nrf;
int f[mmax + 1][ 2 ];
Muchie w[mmax + 1];
pair< int, int > pos[mmax + 1];

bool viz[mmax + 1];
int cul[mmax + 1], grad[mmax + 1];
vector< int > ord;

graf g[nmax + 1];
graf gf[mmax + 1];

inline double unghi( Pct a, Pct b ) {
    double u = atan2( b.y - a.y, b.x - a.x ) / M_PI * 180;
    if (u < 0) u += 360;
    return u;
}
inline bool cmp( int a, int b ) {
    Pct ca = v[ w[ a ].capat( c ) ], cb = v[ w[ b ].capat( c ) ];
    return unghi( v[ c ], ca ) < unghi( v[ c ], cb );
}
void citire() {
    fscanf(fin, "%d%d", &n, &m);

    for (int i = 1; i <= n; ++ i) {
        fscanf(fin, "%lf%lf", &v[ i ].x, &v[ i ].y);
    }

    for (int i = 1; i <= m; ++ i) {
        fscanf(fin, "%d%d", &w[ i ].x, &w[ i ].y);
        g[ w[ i ].x ].push_back( i );
        g[ w[ i ].y ].push_back( i );
    }
}
void precalc() {
    for (int i = 1; i <= n; ++ i) {
        c = i;
        sort(g[ i ].begin(), g[ i ].end(), cmp);
        for (int j = 0; j < (int)g[ i ].size(); ++ j) {
            if (i == w[ g[ i ][ j ] ].x) {
                pos[ g[ i ][ j ] ].first = j;
            } else {
                pos[ g[ i ][ j ] ].second = j;
            }
        }
    }
}
void du_te( int nod, int muchie, int stop ) {
    do {
        int p;
        if (nod == w[ muchie ].y) {
            f[ muchie ][ 0 ] = nrf;
            p = pos[ muchie ].second;
        } else {
            f[ muchie ][ 1 ] = nrf;
            p = pos[ muchie ].first;
        }
        muchie = g[ nod ][ (p - 1 + (int)g[ nod ].size()) % (int)g[ nod ].size() ];

        nod = w[ muchie ].capat( nod );
    } while (nod != stop);
}
void calc_fete_si_graf() {
    nrf = 0;
    for (int i = 1; i <= m; ++ i) {
        if (f[ i ][ 0 ] == 0) { // incep sa o parcurg in sensul ei
            ++ nrf;
            du_te( w[ i ].y, i, w[ i ].y );
        }
        if (f[ i ][ 1 ] == 0) {
            ++ nrf;
            du_te( w[ i ].x, i, w[ i ].x );
        }
    }

    for (int i = 1; i <= m; ++ i) {
        gf[ f[ i ][ 0 ] ].push_back( f[ i ][ 1 ] );
        gf[ f[ i ][ 1 ] ].push_back( f[ i ][ 0 ] );
    }
}
void coloreaza() {
    for (int i = 1; i <= nrf; ++ i) {
        grad[ i ] = (int)g[ i ].size();
        s.insert( str(i, grad[ i ]) );
    }

    for (int i = 1; i <= nrf; ++ i) {
        str x = *(s.begin());
        s.erase( s.begin() );
        viz[ x.nod ] = 1;
        ord.push_back( x.nod );
        for (auto j : gf[ x.nod ]) {
            if (viz[ j ]) continue;
            s.erase( str( j, grad[ j ]) );
            -- grad[ j ];
            s.insert( str( j, grad[ j ] ) );
        }
    }

    for (auto i : ord) {
        bool fol[ 7 ] = { 0, 0, 0, 0, 0, 0, 0 };
        viz[ i ] = 0;
        for (auto j : gf[ i ]) {
            if (viz[ j ]) continue;
            fol[ cul[ j ] ] = 1;
        }
        for (int j = 1; j <= 6; ++ j) {
            if (fol[ j ] == 0) {
                cul[ i ] = j; break;
            }
        }
    }
}
void afiseaza() {
    for (int i = 1; i <= m; ++ i) {
        int ans = cul[ f[ i ][ 0 ] ] - cul[ f[ i ][ 1 ] ];
        if (ans > 0) {
            fprintf(fout, "%d %d %d\n", w[ i ].x, w[ i ].y, ans );
        } else {
            fprintf(fout, "%d %d %d\n", w[ i ].y, w[ i ].x, -ans );
        }
    }
}
int main() {
    citire();
    precalc();
    calc_fete_si_graf();
    coloreaza();
    afiseaza();

    fclose(fin);
    fclose(fout);
    return 0;
}