Pagini recente » Cod sursa (job #1352071) | Cod sursa (job #2585403) | Cod sursa (job #1043904) | Cod sursa (job #2356274) | Cod sursa (job #1940196)
#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;
}