Cod sursa(job #959546)

Utilizator mugurelionutMugurel-Ionut Andreica mugurelionut Data 8 iunie 2013 13:38:50
Problema Nowhere-zero Scor 20
Compilator cpp Status done
Runda Infoarena Cup 2013 Marime 5.35 kb
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <set>

using namespace std;

#define DEBUG 0
#define NMAX 100100

double x[NMAX], y[NMAX];
vector<int> vec[NMAX];
int N, M;

void ReadInput() {
    int i, j, k;

    freopen("nowhere-zero.in", "r", stdin);
    scanf("%d %d", &N, &M);
    for (i = 1; i <= N; i++)
        scanf("%lf %lf", &(x[i]), &(y[i]));
    for (k = 1; k <= M; k++) {
        scanf("%d %d", &i, &j);
        vec[i].push_back(j);
        vec[j].push_back(i);
    }
}

int vv[NMAX][8], nv[NMAX];
set<pair<int, int> > h;
int o[NMAX], po[NMAX], deg[NMAX];
pair<int, int> p;

void RemoveNodes() {
    int i, j, k, M = 0;

    if (N == 1)
        return;

    for (i = 1; i <= N; i++) {
        deg[i] = vec[i].size();
        po[i] = 0;
        h.insert(make_pair(deg[i], i));
    }

    while (h.size() > 0) {
        p = *(h.begin());
        h.erase(p);

        i = p.second;
        M++;
        o[M] = i;
        po[i] = M;
        nv[M] = 0;

        for (k = 0; k < vec[i].size(); k++) {
            j = vec[i][k];
            if (po[j] > 0)
                continue;
            vv[M][nv[M]] = j;
            nv[M]++;
            h.erase(make_pair(deg[j], j));
            deg[j]--;
            h.insert(make_pair(deg[j], j));
        }
    }

    if (DEBUG) {
        for (k = M; k >= 1; k--) {
            fprintf(stderr, "k=%d: node=%d nv=%d\n", k, o[k], nv[k]);
        }
    }
}

int visited[NMAX], visited_idx;
vector<pair<int, int> > out[NMAX];
int q[NMAX], pa[NMAX], ipa[NMAX], li, ls;

int FindPath(int start, int finish, int excluded, int push) {
    int i, j, k;

    visited_idx++;
    q[li = ls = 1] = start;
    pa[start] = 0;
    visited[start] = visited_idx;

    while (li <= ls && visited[finish] != visited_idx) {
        i = q[li];
        li++;
        for (k = 0; k < out[i].size(); k++) {
            j = out[i][k].first;
            if (j == excluded)
                continue;

            if (visited[j] != visited_idx) {
                visited[j] = visited_idx;
                ls++;
                q[ls] = j;
                pa[j] = i;
                ipa[j] = k;
                if (j == finish)
                    break;
            }
        }
    }

    if (visited[finish] == visited_idx) {
        i = finish;
        while (i != start) {
            out[pa[i]][ipa[i]].second += push;
            i = pa[i];
        }
        return 1;
    }

    return 0;
}

void Solve() {
    int i, j, p, k;

    visited_idx = 0;

    for (k = N; k >= 1; k--) {
        i = o[k];
        if (nv[k] == 0)
            continue;
        else if (nv[k] == 1) {
            out[i].push_back(make_pair(vv[k][0], 0));
        } else if (nv[k] == 2) {
            if (FindPath(vv[k][0], vv[k][1], 0, 1)) {
                out[i].push_back(make_pair(vv[k][0], 1));
                out[vv[k][1]].push_back(make_pair(i, 1));
            } else {
                if (!FindPath(vv[k][1], vv[k][0], 0, 1)) {
                    return;
                }
                out[i].push_back(make_pair(vv[k][1], 1));
                out[vv[k][0]].push_back(make_pair(i, 1));
            }
        } else if (nv[k] == 3) {
            if (FindPath(vv[k][0], vv[k][1], /*vv[k][2]*/ 0, 2)) {
                if (!FindPath(vv[k][1], vv[k][2], /*vv[k][0]*/ 0, 1)) {
                    //exit(1);
                    return;
                }
                out[i].push_back(make_pair(vv[k][0], 2));
                out[vv[k][1]].push_back(make_pair(i, 1));
                out[vv[k][2]].push_back(make_pair(i, 1));
            } else
            if (FindPath(vv[k][1], vv[k][0], /*vv[k][2]*/ 0, 2)) {
                if (!FindPath(vv[k][0], vv[k][2], /*vv[k][1]*/ 0, 1)) {
                    exit(1);
                    return;
                }
                out[i].push_back(make_pair(vv[k][1], 2));
                out[vv[k][0]].push_back(make_pair(i, 1));
                out[vv[k][2]].push_back(make_pair(i, 1));
            } else
            if (FindPath(vv[k][0], vv[k][2], /*vv[k][1]*/ 0, 2)) {
                if (!FindPath(vv[k][2], vv[k][1], /*vv[k][0]*/ 0, 1)) {
                    //exit(1);
                    return;
                }
                out[i].push_back(make_pair(vv[k][0], 2));
                out[vv[k][2]].push_back(make_pair(i, 1));
                out[vv[k][1]].push_back(make_pair(i, 1));
            } else
            if (FindPath(vv[k][2], vv[k][0], /*vv[k][1]*/ 0, 2)) {
                if (!FindPath(vv[k][0], vv[k][1], /*vv[k][2]*/ 0, 1)) {
                    //exit(1);
                    return;
                }
                out[i].push_back(make_pair(vv[k][2], 2));
                out[vv[k][0]].push_back(make_pair(i, 1));
                out[vv[k][1]].push_back(make_pair(i, 1));
            } else {
                //exit(1);
                return;
            }
        } else {
            //exit(1);
            return;
        }
    }
}

void WriteOutput() {
    int i, j;
    freopen("nowhere-zero.out", "w", stdout);
    for (i = 1; i <= N; i++)
        for (j = 0; j < out[i].size(); j++)
            printf("%d %d %d\n", i, out[i][j].first, out[i][j].second);
}

int main() {
    ReadInput();
    RemoveNodes();
    Solve();
    WriteOutput();
    return 0;
}