Cod sursa(job #959440)

Utilizator goguGogu Marian gogu Data 8 iunie 2013 12:49:38
Problema Nowhere-zero Scor 10
Compilator cpp Status done
Runda Infoarena Cup 2013 Marime 3.14 kb
#include <cstdio>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <algorithm>

using namespace std;

#define MaxN 100100

struct Edge {
    int vec, flux;
    Edge(int v) {
        vec = v;
        flux = 0;
    }
};

pair<double, double> points[MaxN];

int N, M, doneEdges = 0;
vector<Edge> edges[MaxN];
int cd[MaxN], t[MaxN];
bool viz[MaxN], haveTouched[MaxN];
int startNode = 0, sizeCd = 0;
bool stillCycling;

void SetTata(int poz, int val) {
    t[poz] = val;
    cd[sizeCd++] = poz;
}

void ClearTati() {
    for (int i = 0; i < sizeCd; i++) {
        t[cd[i]] = -1;
    }
    sizeCd = 0;
}

bool CompFlux(const Edge &a, const Edge &b) {
    return a.flux < b.flux;
}

bool CompFluxDist(const Edge &a, const Edge &b) {
}

void IncremFlow(int x, int y, int flux) {
    for (size_t i = 0; i < edges[x].size(); i++) {
        if (edges[x][i].vec == y) {
            doneEdges += (edges[x][i].flux == 0 && flux > 0);
            edges[x][i].flux += flux;
            return;
        }
    }
}

void MarkEdge(int x, int y) {
    IncremFlow(x, y, 1);
    IncremFlow(y, x, -1);
}

bool HaveEdges(int x) {
    for (size_t i = 0; i < edges[x].size(); i++) {
        if (edges[x][i].flux == 0) {
            return true;
        }
    }
    return false;
}

void ReversePath(int nod) {
    MarkEdge(nod, startNode);
    while (nod != startNode) {
        MarkEdge(t[nod], nod);
        nod = t[nod];
    }
}

void df(int nod) {
    //sort(edges[nod].begin(), edges[nod].end(), CompFlux);
    for (int i = 0; i < (int)edges[nod].size() && stillCycling; i++) {
        const int vec = edges[nod][i].vec;
        if (edges[nod][i].flux >= 0 && t[vec] == -1 && vec != t[nod]) {

            if (vec == startNode) {
                stillCycling = false;
                ReversePath(nod);
                return;
            }

            SetTata(vec, nod);
            df(vec);
        }
    }
}

void FindCycle() {
    while (!HaveEdges(startNode) && startNode < N) {
        startNode++;
    }

    stillCycling = true;

    for (size_t i = 0; i < edges[startNode].size(); i++) {
        if (edges[startNode][i].flux == 0) {
            const int v = edges[startNode][i].vec;
            SetTata(v, startNode);
            df(v);
            ClearTati();
            return;
        }
    }
}

int main() {
    freopen("nowhere-zero.in", "rb", stdin);
    freopen("nowhere-zero.out", "wb", stdout);
    scanf("%d %d\n", &N, &M);

    for (int i = 0; i < N; i++) {
        scanf("%lf %lf", &points[i].first, &points[i].second);
    }

    for (int i = 0; i < M; i++) {
        int x, y;
        scanf("%d %d", &x, &y);
        x--; y--;
        edges[x].push_back(y);
        edges[y].push_back(x);
    }

    memset(t, -1, sizeof(int) * N);

    while (doneEdges < M) {
        FindCycle();
    }

    for (int i = 0; i < N; i++) {
        for (size_t j = 0; j < edges[i].size(); j++) {
            if (edges[i][j].flux > 0) {
                printf("%d %d %d\n", i + 1, edges[i][j].vec + 1, edges[i][j].flux);
            }
        }
    }

    return 0;
}