Cod sursa(job #1546192)

Utilizator PTAdrian64Pop-Tifrea Adrian PTAdrian64 Data 7 decembrie 2015 19:57:15
Problema Ciclu Eulerian Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.73 kb
#include <cstdio>
#include <list>
#include <queue>
#define maxl 100005
#include <stack>
/**Fie un multigraf G = (V,E). Un ciclu al lui G se numeste Eulerian daca viziteaza toate muchiile din E exact o singura data.
G se numeste Eulerian daca admite un ciclu Eulerian.

Cerinta
Fiind dat un multigraf G = (V,E), determinati daca acesta este Eulerian. In caz afirmativ, gasiti un ciclu Eulerian al sau.

Date de intrare
Fisierul de intrare ciclueuler.in contine pe prima linie numerele N si M, reprezentand numarul nodurilor,
 respectiv numarul muchiilor din G. Pe urmatoarele M linii se afla cate o pereche de numere u v, decriind o muchie a
  multigrafului, cu extremitatile in nodurile u si v.

Date de iesire
In fisierul de iesire ciclueuler.out veti tipari M numere x1 x2 ... xM, cu proprietatea ca (x1,x2), (x2,x3), ..., (xM,x1) sunt
 muchiile ciclului Eulerian determinat, sau numarul -1, in cazul in care G nu este Eulerian.

Restrictii
1 ≤ N ≤ 100 000
1 ≤ M ≤ 500 000
Solutia nu este unica; orice solutie valida va primi punctajul maxim.
*/
using namespace std;

int N,M,d[maxl];
bool viz[maxl];
list <int> G[maxl],A;
queue <int> Q;
stack <int> S;

void Read();
void Losung();
void BFS(){
    Q.push(1);
    viz[1]=true;
    int x;
    while(!Q.empty()){
        x=Q.front();
        Q.pop();
        for(list <int>::iterator it=G[x].begin();it!=G[x].end();++it)
        if(viz[*it]==false){
            viz[*it]=true;
            Q.push(*it);
        }
    }
}
void Scrie(){
    for(list <int> :: iterator it=A.begin();it!=A.end();++it)printf("%d ",*it);
    printf("\n");
}
int main(){
    freopen("ciclueuler.in","r",stdin);
    freopen("ciclueuler.out","w",stdout);
    Read();
    Losung();
    return 0;
}
void Read(){
    scanf("%d %d ",&N,&M);
    int x,y;
    while(M--){
        scanf("%d %d ",&x,&y);
        d[x]++;d[y]++;
        G[x].push_back(y);
        G[y].push_back(x);
    }
}
void Losung(){
    int i;
    ///verificam ca fiecare nod sa aiba grad par:
    for(i=1;i<=N;++i)if(d[i]%2==1){printf("-1");return;}
    ///varificam ca graful este conex:
    BFS();
    for(i=1;i<=N;++i)if(viz[i]==false){printf("-1");return;}
    ///daca este graf eulerian, cautam un ciclu eulerian:
    int v=1,w;
    do{
        while(!G[v].empty()){
            w=G[v].front();
            S.push(v);
            ///stergem muchiile v-w si w-g:
            G[v].pop_front();
            for(list <int>::iterator it=G[w].begin();it!=G[w].end();++it)
               if(*it==v){
                  G[w].erase(it);
                  break;
               }
            v=w;
        }
        v=S.top();
        S.pop();
        A.push_back(v);
    }while(!S.empty());
    Scrie();
}