Cod sursa(job #1724344)

Utilizator retrogradLucian Bicsi retrograd Data 2 iulie 2016 21:43:02
Problema Nowhere-zero Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.75 kb
#include <bits/stdc++.h>

using namespace std;

typedef complex<double> Point;
#define x real()
#define y imag()

const int kMaxM = 800005;
const int kMaxN = 100005;

int Vec[kMaxM], F[kMaxM], Pos[kMaxM], Face[kMaxM];
bool Used[kMaxM];
int n, m, faces;

vector<int> G[kMaxN], Gf[kMaxM];
Point Points[kMaxN];

int Color[kMaxM], Deg[kMaxM];

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

    double x1, x2;
    cin >> n >> m;

    for(int i = 1; i <= n; ++i) {
        cin >> x1 >> x2;
        Points[i] = Point(x1, x2);
    }

    for(int i = 1; i <= m; ++i) {
        cin >> Vec[2 * i] >> Vec[2 * i + 1];
        G[Vec[2 * i + 1]].push_back(2 * i);
        G[Vec[2 * i]].push_back(2 * i + 1);
    }

    for(int i = 1; i <= n; ++i) {
        sort(G[i].begin(), G[i].end(), [&i] (int a, int b) {
            Point pa = Points[Vec[a]] - Points[i];
            Point pb = Points[Vec[b]] - Points[i];

            return atan2(pa.y, pa.x) < atan2(pb.y, pb.x);
        });

        for(int j = 0; j < G[i].size(); ++j) {
            Pos[G[i][j]] = j;
        }
    }

    for(int i = 2; i <= 2 * m + 1; ++i) {
        if(!Used[i]) {
            ++faces;

            int start = Vec[i ^ 1],
                node = start,
                edge = i,
                pos;

            do {
                assert(!Used[edge]);

                Used[edge] = true;
                Face[edge] = faces;
                node = Vec[edge];

                pos = (Pos[edge ^ 1] + 1) % G[node].size();
                edge = G[node][pos];
            } while(node != start);
        }
    }

    for(int i = 2; i <= 2 * m + 1; ++i) {
        Gf[Face[i]].push_back(Face[i ^ 1]);
    }

    vector<int> V;
    for(int i = 1; i <= faces; ++i) {
        Deg[i] = Gf[i].size();
        if(Deg[i] <= 5) V.push_back(i);
    }

    for(int i = 0; i < V.size(); ++i) {
        int node = V[i];
        for(auto vec : Gf[node]) {
            if(--Deg[vec] == 5)
                V.push_back(vec);
        }
    }

    assert(V.size() == faces);

    while(!V.empty()) {
        int node = V.back();
        V.pop_back();

        vector<bool> Has(7);
        for(auto vec : Gf[node])
            Has[Color[vec]] = 1;

        Color[node] = 1;
        while(Has[Color[node]]) ++Color[node];

        assert(Color[node] <= 6);
    }

    for(int i = 1; i <= m; ++i) {
        int flow = Color[Face[2 * i]] - Color[Face[2 * i + 1]];
        if(flow < 0) {
            cout << Vec[2 * i] << " " << Vec[2 * i + 1] << " " << -flow << '\n';
        } else {
            cout << Vec[2 * i + 1] << " " << Vec[2 * i] << " " << flow << '\n';
        }
    }

    return 0;
}