Cod sursa(job #959550)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 8 iunie 2013 13:40:15
Problema Nowhere-zero Scor 0
Compilator cpp Status done
Runda Infoarena Cup 2013 Marime 2.81 kb
#include <cstdio>
#include <cmath>
#include <cassert>

#include <algorithm>
#include <vector>
#include <map>

using namespace std;

const int MAX_V = 100005;
const int MAX_E = 350005;

class Point {
  public:
    double x, y;

    Point() {}

    Point(const double x, const double y) {
        this->x = x;
        this->y = y;
    }
};

class Edge {
  public:
    int x, y;

    Edge() {}

    Edge(const int x, const int y) {
        this->x = x;
        this->y = y;
    }

    bool operator<(const Edge &other) const {
        if (x != other.x)
            return x < other.x;
        return y < other.y;
    }
};

Point Points[MAX_V], Center;
vector<int> G[MAX_V];
Edge Edges[MAX_E];
int V, E;
map<Edge, int> Index, Next, Flow;

class Compare {
  public:
    bool operator()(const int &x, const int &y) const {
        return atan2(Points[x].y - Center.y, Points[x].x - Center.y) < atan2(Points[y].y - Center.y, Points[y].x - Center.x);
    }
};

void BuildGraph() {
    for (int x = 1; x <= V; ++x) {
        if (G[x].empty())
            continue;
        Center = Points[x];
        sort(G[x].begin(), G[x].end(), Compare());
        G[x].push_back(G[x].front());
        for (int i = 0; i + 1 < static_cast<int>(G[x].size()); ++i)
            Next[Edge(G[x][i], x)] = G[x][i + 1];
    }
}

void Solve() {
    BuildGraph();
    for (int i = 1; i <= E; ++i) {
        Edge e = Edges[i];
        if (Flow[e] != 0)
            continue;
        int start = e.x, direction = 1, x, y;
        x = e.x; y = e.y;
        do {
            if (Flow[Edge(x, y)] == -1)
                direction = -1;
            int z = Next[Edge(x, y)];
            x = y;
            y = z;
        } while (x != start);
        x = e.x; y = e.y;
        do {
            Flow[Edge(x, y)] += direction;
            Flow[Edge(y, x)] -= direction;
            int z = Next[Edge(x, y)];
            x = y;
            y = z;
        } while (x != start);
    }
}

void Read() {
    assert(freopen("nowhere-zero.in", "r", stdin));
    assert(scanf("%d %d", &V, &E) == 2);
    for (int i = 1; i <= V; ++i)
        assert(scanf("%lf %lf", &Points[i].x, &Points[i].y) == 2);
    for (int i = 1; i <= E; ++i) {
        int x, y; assert(scanf("%d %d", &x, &y) == 2);
        Edges[i] = Edge(x, y);
        Index[Edge(x, y)] = Index[Edge(y, x)] = i;
        Flow[Edge(x, y)] = Flow[Edge(y, x)] = 0;
        G[x].push_back(y); G[y].push_back(x);
    }
}

void Print() {
    assert(freopen("nowhere-zero.out", "w", stdout));
    for (int i = 1; i <= E; ++i) {
        if (Flow[Edges[i]] < 0)
            swap(Edges[i].x, Edges[i].y);
        printf("%d %d %d\n", Edges[i].x, Edges[i].y, Flow[Edges[i]]);
    }
}

int main() {
    Read();
    Solve();
    Print();
    return 0;
}