Cod sursa(job #1743692)

Utilizator fanache99Constantin-Buliga Stefan fanache99 Data 18 august 2016 16:13:16
Problema Nowhere-zero Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.8 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
using namespace std;

ifstream cin("nowhere-zero.in");
ofstream cout("nowhere-zero.out");

const int MAXN = 100000;

int n, m, pivot;
int regions = 0;
double X[1 + MAXN], Y[1 + MAXN];
vector<pair<int, int> > g[1 + MAXN];
vector<int> graph[1 + 3 * MAXN], order;
vector<bool> usedEdge[1 + MAXN];
map<int, int> edgeIndex[1 + MAXN];
pair<int, int> orientation[1 + 3 * MAXN], region[1 + 3 * MAXN];
set<pair<int, int> > Set;
int color[1 + 3 * MAXN], degree[1 + 3 * MAXN];
bool seen[1 + 3 * MAXN], usedColor[7];

bool Compare(const pair<int, int> &a, const pair<int, int> &b) {
    return atan2(Y[a.first] - Y[pivot], X[a.first] - X[pivot]) < atan2(Y[b.first] - Y[pivot], X[b.first] - Y[pivot]);
}

void ComputeRegionGraph() {
    for (int i = 1; i <= n; i++) {
        pivot = i;
        sort(g[i].begin(), g[i].end(), Compare);
        usedEdge[i].resize(g[i].size(), false);
        for (int j = 0; j < g[i].size(); j++)
            edgeIndex[i][g[i][j].first] = j;
    }
    for (int i = 1; i <= n; i++)
        for (int j = 0; j < g[i].size(); j++)
            if (!usedEdge[i][j]) {
                regions++;
                int node = i, edge = j;
                do {
                    usedEdge[node][edge] = true;
                    int nextNode = g[node][edge].first;
                    int nextEdge = g[node][edge].second;
                    if (region[nextEdge].first == 0) {
                        region[nextEdge].first = regions;
                        orientation[nextEdge] = make_pair(node, nextNode);
                    }
                    else
                        region[nextEdge].second = regions;
                    edge = edgeIndex[nextNode][node] + 1;
                    if (edge == g[nextNode].size())
                        edge = 0;
                    node = nextNode;
                } while (node != i);
            }
    for (int i = 1; i <= m; i++) {
        graph[region[i].first].push_back(region[i].second);
        graph[region[i].second].push_back(region[i].first);
    }
}

void ColorRegionGraph() {
    for (int i = 1; i <= regions; i++) {
        degree[i] = graph[i].size();
        Set.insert(make_pair(graph[i].size(), i));
    }
    while (!Set.empty()) {
        pair<int, int> current = *Set.begin();
        int node = current.first;
        Set.erase(current);
        if (seen[node])
            continue;
        seen[node] = true;
        order.push_back(node);
        for (auto &nextNode : graph[node])
            if (!seen[nextNode]) {
                Set.erase(make_pair(degree[nextNode], nextNode));
                degree[nextNode]--;
                Set.insert(make_pair(degree[nextNode], nextNode));
            }
    }
    for (int i = regions - 1; i >= 0; i--) {
        int node = order[i];
        for (int j = 1; j <= 6; j++)
            usedColor[j] = false;
        for (auto &neighbour : graph[node])
            usedColor[color[neighbour]] = true;
        int j = 1;
        while (usedColor[j])
            j++;
        color[node] = j;
    }
}

int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        cin >> X[i] >> Y[i];
    for (int i = 1; i <= m; i++) {
        int a, b;
        cin >> a >> b;
        g[a].push_back(make_pair(b, i));
        g[b].push_back(make_pair(a, i));
    }
    ComputeRegionGraph();
    ColorRegionGraph();
    for (int i = 1; i <= m; i++) {
        int a = orientation[i].first, b = orientation[i].second, flow = color[region[i].first] - color[region[i].second];
        if (flow > 0)
            cout << a << " " << b << " " << flow << "\n";
        else
            cout << b << " " << a << " " << -flow << "\n";
    }
    return 0;
}