Cod sursa(job #959532)

Utilizator mihai995mihai995 mihai995 Data 8 iunie 2013 13:33:46
Problema Nowhere-zero Scor 20
Compilator cpp Status done
Runda Infoarena Cup 2013 Marime 2.62 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;

const int N = 100002;

struct Edge{
    int x, y, val;

    Edge(int _x, int _y, int _val){
        x = _x;
        y = _y;
        val = _val;
    }

    void swap(int nVal){
        std::swap(x, y);
        val = nVal;
    }
};

vector<int> graph[N];
vector<Edge> edge;
int grad[N], n;
int color[N];
bool use[7 * N];

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

void dfs(int x, int T){
    if (T != 0 && color[x] < 2){
        edge.push_back(Edge(T, x, 1));
        grad[x]--;
        grad[T]++;
    }

    if (color[x])
        return;

    color[x] = 1;

    for (vector<int> :: iterator it = graph[x].begin() ; it != graph[x].end() ; it++)
        if (*it != T)
            dfs(*it, x);

    color[x] = 2;
}

inline bool over(){
    for (int i = 1 ; i <= n ; i++)
        if (grad[i] != 0)
            return false;
    return true;
}

void fullUp(){
    int x, y, val, nV;

    for (vector<Edge> :: iterator it = edge.begin() ; it != edge.end() ; it++){
        x = it -> x;
        y = it -> y;
        val = it -> val;

        if (grad[x] > 0 && grad[y] < 0){
            grad[x] -= val;
            grad[y] += val;
            nV = min(5, min(grad[x], -grad[y]));

            if (nV <= 0)
                nV = 1;

            it -> swap(nV);

            grad[y] += nV;
            grad[x] -=nV;
        }
    }
}

void partialUp(){
    int x, y, val, nV, times = 200, p;

    memset(use, false, sizeof(use));

    while (times--){
        p = rand() % edge.size();
        if (use[p])
            continue;

        use[p] = true;

        x = edge[p].x;
        y = edge[p].y;
        val = edge[p].val;

        if (grad[x] > 0 || grad[y] < 0){
            grad[x] -= val;
            grad[y] += val;

            nV = min(5, max(grad[x], -grad[y]));

            if (nV <= 0)
                nV = 1;

            edge[p].swap(nV);

            grad[y] += nV;
            grad[x] -=nV;
        }
    }
}

int main(){
    double shitA, shitB;
    int m, x, y;
    in >> n >> m;

    for (int i = 1 ; i <= n ; i++)
        in >> shitA >> shitB;

    while (m--){
        in >> x >> y;
        graph[x].push_back(y);
        graph[y].push_back(x);
    }

    dfs(1, 0);

    while (!over()){
        fullUp();
        partialUp();
    }

    for (vector<Edge> :: iterator it = edge.begin() ; it != edge.end() ; it++)
        out << (it -> x) << " " << (it -> y) << " " << (it -> val) << "\n";

    return 0;
}