Cod sursa(job #1975775)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 1 mai 2017 21:54:39
Problema Nowhere-zero Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.01 kb
#include <bits/stdc++.h>
using namespace std;
 
using cd = complex<double>;
 
ifstream f("nowhere-zero.in");
ofstream g("nowhere-zero.out");
 
static vector<int> color_graf(const vector<vector<int>>& graf){
    const int n = graf.size();
    vector<int> rez(n, -1), deg(n, 0), ord;
    for(int i = 0; i < n; ++i) deg[i] = graf[i].size();
 
    queue<int> de_viz;
    for(int i = 0; i < n; ++i)
        if(deg[i] < 6) de_viz.push(i);
 
    while(!de_viz.empty()){
        const int cur = de_viz.front();
        de_viz.pop();
        ord.push_back(cur);
        for(const auto next : graf[cur]){
            --deg[next];
            if(deg[next] == 5) de_viz.push(next); } }
    reverse(begin(ord), end(ord));
    for(const auto x : ord){
        bitset<6> has_been_seen = 0;
        for(const auto next : graf[x])
            if(rez[next] >= 0) has_been_seen[rez[next]] = 1;
        for(rez[x] = 5; has_been_seen[rez[x]]; --rez[x]); }
    return rez; }
 
int main(){
    int n, m;
    f >> n >> m;
 
    vector<cd> pts(n);
    for(auto& x : pts){
        double a, b;
        f >> a >> b;
        x = cd { a, b }; }
 
    vector<vector<int>> graf_init(n);
    vector<pair<int, int>> muchii;
    for(int i = 0, x, y; i < m; ++i){
        f >> x >> y;
        --x, --y;
        muchii.emplace_back(x, y);
        muchii.emplace_back(y, x);
        graf_init[x].push_back(y);
        graf_init[y].push_back(x); }
 
    for(int i = 0; i < n; ++i)
        sort(begin(graf_init[i]), end(graf_init[i]),
            [&](const int a, const int b){
                return arg(pts[a] - pts[i]) < arg(pts[b] - pts[i]); });
 
    const int faces = m - n + 2;
 
    vector<unordered_map<int, int>> which_face(n);
 
    int cur_face = 0;
    for(const auto x : muchii){
        if(which_face[x.first].find(x.second) != end(which_face[x.first])) continue;
        int a = x.first, b = x.second;
        do{
            which_face[a][b] = cur_face;
            auto it = upper_bound(begin(graf_init[b]), end(graf_init[b]), a,
                [&](const int x, const int y){
                    return arg(pts[x] - pts[b]) < arg(pts[y] - pts[b]); });
            const int c = (it == end(graf_init[b]) ? graf_init[b][0] : *it);
            a = b, b = c;
        } while(a != x.first && b != x.second);
        ++cur_face; }
 
    vector<vector<int>> graf_face(faces);
 
    for(const auto x : muchii)
        graf_face[which_face[x.first][x.second]].push_back(
            which_face[x.second][x.first]);
 
    for(auto& x : graf_face){
        sort(begin(x), end(x));
        x.erase(unique(begin(x), end(x)), end(x)); }
 
    auto coloring = color_graf(graf_face);
 
    vector<int> flux(n, 0);
 
    for(const auto x : muchii){
        const int val = coloring[which_face[x.first][x.second]] - coloring[which_face[x.second][x.first]];
        if(val < 0) continue;
        g << x.first+1 << ' ' << x.second+1 << ' ' << val << '\n';
        flux[x.second] += val;
        flux[x.first] -= val; }
    assert(all_of(begin(flux), end(flux), [](const int x){ return x == 0; }));
     
    return 0; }