Cod sursa(job #959565)

Utilizator repp4raduRadu-Andrei Szasz repp4radu Data 8 iunie 2013 13:47:22
Problema Nowhere-zero Scor 10
Compilator cpp Status done
Runda Infoarena Cup 2013 Marime 3.37 kb
#include <fstream>
#include <vector>
#include <iostream>
#include <queue>
#include <cstring>

#define f first
#define s second

using namespace std;

const int MAX = 100005;

int N, M, R, cc;
double X, Y;
bool created;

int CC[MAX], muchie[MAX], dad[MAX];
bool used[2 * MAX], viz[MAX];
int increased[2 * MAX];
pair<int, int> G[2 * MAX];

vector< int > V[MAX], solution;
vector< int >::iterator IT[MAX];

queue<int> Q;

void citire() {
    ifstream in("nowhere-zero.in");
    in >> N >> M;
    for(int i = 1; i <= N; i++) {
        in >> X >> Y;
    }
    for(int i = 1; i <= M; i++) {
        in >> G[i].f >> G[i].s;
        V[ G[i].f ].push_back(i);
        V[ G[i].s ].push_back(i);
    } in.close();
}

void eulerian(int nod) {
    while(IT[nod] != V[nod].end()) {
        if(used[(*IT[nod])]) {
            IT[nod]++;
            continue;
        }
        used[ *IT[nod] ] = true;
        int neighbour = G[ *IT[nod] ].f + G[ *IT[nod] ].s - nod;
        if(neighbour == G[ *IT[nod] ].f) {
            swap(G[ *IT[nod] ].f, G[ *IT[nod] ].s);
        }
        IT[nod]++;
        eulerian(neighbour);
    }
    solution.push_back(nod);
}

void incrementRoad(int start, int stop) {
    while(stop != start) {
        increased[ muchie[stop] ]++;
        stop = dad[stop];
    }
}

void findRoad(int start, int stop) {
    memset(viz, 0, sizeof(viz));
    while(!Q.empty()) Q.pop();
    Q.push(start); viz[start] = true;
    while(!Q.empty()) {
        int nod = Q.front(); Q.pop();
        for(size_t i = 0; i < V[nod].size(); i++) {
            int dest = G[ V[nod][i] ].f;
            if(dest == nod || dest == R || increased[ V[nod][i] ] == 5) continue;
            Q.push(dest);
            viz[dest] = true;
            dad[dest] = nod;
            muchie[dest] = V[nod][i];
            if(dest == stop) {
                incrementRoad(start, stop);
                return;
            }
        }
    }
}

void solve() {
    for(size_t i = 0; i < solution.size(); i++) {
        //cout << solution[i] << " ";
        if(solution[i] == R) {
            findRoad(solution[i - 1], solution[i + 1]);
        }
    }
}

void dfs(int nod, int cc) {
    CC[nod] = cc;
    for(size_t i = 0; i < V[nod].size(); i++) {
        int neighbour = G[ V[nod][i] ].f + G[ V[nod][i] ].s - nod;
        if(!CC[neighbour]) dfs(neighbour, cc);
    }
}

void preprocess() {
    created = false;
    R = N + 1;
    V[R].clear();
    for(int i = 1; i <= N; i++) {
        if(CC[i] == cc && V[i].size() % 2 == 1) {
            if(!created) created = true;
            G[++M].f = i; G[M].s = R;
            V[R].push_back(M);
            V[i].push_back(M);
        }
        if(CC[i] == cc) {
            IT[i] = V[i].begin();
        }
    }
    if(created) IT[R] = V[R].begin();
}

void afisare() {
    ofstream out("nowhere-zero.out");
    for(int i = 1; i <= M && G[i].f != R && G[i].s != R; i++) {
        out << G[i].f << " " << G[i].s << " " << increased[i] << "\n";
    }   out.close();
}

int main() {
    citire();
    for(int i = 1; i <= M; i++)
        increased[i] = 1;
    for(int i = 1; i <= N; i++) {
        if(!CC[i]) {
            dfs(i, ++cc);
            preprocess();
            solution.clear();
            eulerian(i);
            if(created) solve();
        }
    }
    afisare();
    return 0;
}