Cod sursa(job #655228)

Utilizator slycerdan dragomir slycer Data 1 ianuarie 2012 20:45:36
Problema Ciclu Eulerian Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 3.27 kb
/* 
 * File:   CicluEulerian.cpp
 * Author: slycer
 *
 * Created on December 31, 2011, 6:30 PM
 */

#include <cstdlib>
#include <vector>
#include <algorithm>
#include <set>
#include <list>
#include <fstream>
#include <iostream>

using namespace std;

ifstream input("ciclueuler.in");
ofstream output("ciclueuler.out");

class Nod{
    
public :
    Nod( int b ){
        this->b = b; 
        marcat = 0; 
    }
    int b;
    int marcat; 
    Nod * frate; 
};

class Graf {
public:
    int n;
    vector<Nod*> *data;
    int *grad;
    Graf( int n ) {
        this->n = n;
        data = new vector<Nod*>[n + 1];
        grad = new int[n + 1];
        for (int i = 0; i <= n; i++) {
            grad[i] = 0;
        }
    }

    void add(int a, int b) {
        Nod *unu = new Nod(b);
        Nod *doi = new Nod(a);
        unu->frate = doi;
        doi->frate = unu;
        data[a].push_back(unu);
        data[b].push_back(doi);
        grad[a]++;
        grad[b]++;
    }

    bool isEulerian() {
        if (!isConnex()) {
            return false;
        }
        for (int i = 1; i <= n; i++) {
            if (grad[i] % 2 == 1) {
                return false;
            }
        }
        return true;
    }

    void printSolution() {
        
        ofstream output("ciclueuler.out");
        int * stack_a = new int[ 500001 ];
        int cap=0; 
        stack_a[cap++] = 1; //.push_back(1);

        while (cap > 0) {
            int a = stack_a[cap-1];//.front();

            bool gata = true;
            while (data[a].size() > 0) {
                gata = false;
                Nod *current = data[a].back();
                data[a].pop_back();
                
                
               // cout << "Push " << current << " " << cap << " " <<endl; 
                if ( !current->marcat )
                {
                        current->frate->marcat = 1; 
                        stack_a[cap++]=current->b;
                        break;
                } else {
                        continue;
                }
            }

            if (gata) {
                if ( a == 1 && cap == 1 ){
                    
                } else {
                        output << a << " ";
                }
                cap--;
            }
        }

    }

    bool isConnex() {
        int * v = new int[100001];
        int cap=0; 
        bool *marcat = new bool[n + 1];
        for (int i = 0; i <= n; i++) {
            marcat[i] = false;
        }
        marcat[1] = true;
        v[cap++] = 1; 
        int op = 0;
        while ( cap > 0 ) {
            op++;
            cap--;
            int current = v[cap];
            vector<Nod*>::iterator i;
            for (i = data[current].begin(); i != data[current].end(); i++) {
                int next = (*i)->b;
                if (!marcat[next]) {
                    v[cap++]= next;
                    marcat[next] = true;
                }
            }
        }
        return op == n;
    }

};

/*
 * 
 */

int main(int argc, char** argv) {


    int n, m;
    input >> n >> m;
    Graf g(n);
    for (int i = 0; i < m; i++) {
        int a, b;
        input >> a >> b;
        g.add(a, b);
        // g.add( b, a );
    }


    if (g.isEulerian()) {
        g.printSolution();
        
    } else {
        output << "-1";
    }
    return 0;
}