Cod sursa(job #1940196)

Utilizator PTAdrian64Pop-Tifrea Adrian PTAdrian64 Data 26 martie 2017 14:49:35
Problema Ciclu Eulerian Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.88 kb
#define MAXN 100002
#include <cstdlib>
#include <stdexcept>
#include <assert.h>
#include <iostream>
#include <vector>
#include <cstdio>
#include <stack>

using namespace std;

/*first element = the index of the edge
* second element = the other end of the edge
*/
std::vector <pair<int, int> > G_Fleury[MAXN];
/**
 * edge_type[i] = 1, if the edge with index i is a tree edge
 * edge_type[i] = 0, if the edge with index i is a turning edge
 * edge_type[i] = -1, if the edge is already visited
 */
int *edge_type;
std::stack <pair<int, int> > S;
int N{0};
int M{0};
bool *viz;

void read_Fleury(){
    freopen("ciclueuler.in", "r", stdin);
    
    scanf("%d %d ", &N, &M);
    viz = new bool[N+1];
    edge_type = new int[M+1];
    int i{1};
    for(i = 1;i <= N;i++)viz[i] = false;
    int x{0}, y{0};
    i = 1;
    while(i <= M){
        scanf("%d %d ", &x, &y);
        G_Fleury[x].push_back(make_pair(i, y));
        G_Fleury[y].push_back(make_pair(i, x));
        i++;
    }
}

bool verify_Euler_Fleury(){
    /*
     * Specification:
     * - Checks if the graph is Eulerian
     * - identify the tree edges - these are the edges marked by DFS
     */
    int i, x, y;
    ///at the beginning, every edge is a turning edge:
    for(i = 1;i <= M;i++)edge_type[i] = false;
    ///first element = the edge index
    ///second element = the node number
    S.push(make_pair(0 ,1));
    while(!S.empty()){
        x = S.top().second;
        y = S.top().first;
        S.pop();
        if(viz[x] == false){
            viz[x] = true;
            ///mark the edge as a tree edge:
            edge_type[y] = true;
            for(i = 0;i < G_Fleury[x].size();i++){
                if(viz[G_Fleury[x][i].second] == false)
                    S.push(make_pair(G_Fleury[x][i].first, G_Fleury[x][i].second));
            }
        }
    }
    for(i = 1;i <= N;i++){
        if(viz[i] == false)return false;
    }
    ///check if every node has an even degree
    for(i = 1;i <= N;i++){
        if(G_Fleury[i].size() %2 == 1)return false;
    }
    return true;
}

void eulerian_ciruit_Fleury(){
    /**
     * Finds an Eulerian circuit in a graph using Fleury algorithm
     * Classify every edge as tree edge or as a turning edge
     * At each step of the algorithm, choose the edge that does not
     * disconnect the graph (a turning edge will always be passed before a 
     * tree edge)
     */
    int i;
    int x;
    read_Fleury();
    ///check if the graph is Eulerian:
    if(!verify_Euler_Fleury()){
        printf("-1\n");
        return;
    }
    /*Now, all we need to do is DFS through the graph, always choosing a
     * turning before a tree edge ( an edge x with edge_type[x] == false):
     */
    x = 1;
    ///stop when we can't move further from the current node
    while(true){
        ///choose the first turning edge
        i = 0;
        while(i < G_Fleury[x].size() && edge_type[G_Fleury[x][i].first]!=0)i++;
        if(i < G_Fleury[x].size()){
            ///this means we found a turning edge
            edge_type[G_Fleury[x][i].first] = -1;
            printf("%d ", x);
            x = G_Fleury[x][i].second;
            continue;
        }
        ///else, find a tree edge:
        i = 0;
        while(i < G_Fleury[x].size() && edge_type[G_Fleury[x][i].first]!=1)i++;
        if(i < G_Fleury[x].size()){
            ///this means we found a tree edge
            edge_type[G_Fleury[x][i].first] = -1;
            printf("%d ", x);
            x = G_Fleury[x][i].second;
            continue;
        }
        ///else, this is the final node from the circuit -> break:
        break;
    }
}

int main() try{
    
    freopen("ciclueuler.out", "w", stdout);
    //eulerian_ciruit_Fleury();
    printf("data");
    
    return 0;
}
catch(...){
    std::cerr << "Unknown error;" << '\n';
    return -1;
}