Cod sursa(job #322534)

Utilizator mika17Mihai Alex Ionescu mika17 Data 9 iunie 2009 01:00:38
Problema Ciclu Eulerian Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 3.39 kb
#include <fstream>
#include <vector>
#include <queue>
#include <bitset>
using namespace std;

ifstream fin("ciclueuler.in");
ofstream fout("ciclueuler.out");

typedef vector<int> vi;
const int NMAX = 10000, MMAX = 500000, start = 0;

int N,M;
vi G[NMAX], Nr[NMAX];

void readGraph() {

     fin>>N>>M;
     
     int x,y;
     for(int i = 0; i < M; ++i) {
             
             fin>>x>>y; --x; --y;
             G[x].push_back(y);
             G[y].push_back(x);
             Nr[x].push_back(i); Nr[y].push_back(i);
     }
}

bool isEuler() {
     
     for(int i = 0; i < N; ++i)
             if(G[i].size() & 1) return false;    
     
     queue <int> Q;
     vector<bool> vis(NMAX,0);
     
     Q.push(start);
     vis[start] = 1;
     
     while(!Q.empty()) {
                       
                       int node = Q.front(); Q.pop();
                       
                       for(vi::iterator p = G[node].begin(); p != G[node].end(); ++p)
                       if(!vis[*p]) {
                                    
                                    Q.push(*p);
                                    vis[*p] = 1;
                       }   
     }
     
     for(int i = 0; i < N; ++i)
             if(!vis[i]) return false;
     
     return true;
}

queue< pair<int,int> > fwd[NMAX],bck[NMAX];

void DFS(int K) {
     
     static bitset<NMAX> vis; static bitset <MMAX> vis2;
     
     vis[K] = 1;
    
     for(vi::iterator p = G[K].begin(); p != G[K].end(); ++p)
     if(!vis[*p]) {

                  fwd[K].push(make_pair(*p, Nr[K][p - G[K].begin()] ) );
                  fwd[*p].push(make_pair(K, Nr[K][p - G[K].begin()] ) );
                  
                  vis2[ Nr[K][p - G[K].begin()] ] = 1;
                  
                  DFS(*p);
     }
       else if(!vis2[ Nr[K][p - G[K].begin()] ] )
         { bck[K].push(make_pair(*p, Nr[K][p - G[K].begin()]) );
           bck[*p].push(make_pair(K, Nr[K][p - G[K].begin()]) );
                  
           vis2[ Nr[K][p - G[K].begin()] ] = 1;;
          }
}

vi cyc;

void getCycle(int K) {
     
     static bitset <MMAX> vis2;
     static int d = 0;
     int node, nr;
     
     if(K == start) if(++d == 2) return;
     cyc.push_back(K);
     bool f = 0;
     while(!bck[K].empty() && !f) {
                         
       node = bck[K].front().first, nr = bck[K].front().second;
       bck[K].pop();
       if(!vis2[ nr ]) f = 1;
     }
     while(!fwd[K].empty() && !f) {
                         
       node = fwd[K].front().first, nr = fwd[K].front().second;
       fwd[K].pop();
       if(!vis2[ nr ]) f = 1;
     }    
     if(f) { vis2[ nr ] = 1; getCycle(node); }
}      

int main() {
    
    readGraph(); 
    if(!isEuler()) fout<<-1;
     else {
          
          DFS(start);
          getCycle(start);
          
          /*
          for(int i = 0; i < N; ++i) {
           while(!fwd[i].empty())
            fout<<fwd[i].front()+1<<' ' , fwd[i].pop();
           fout<<endl;
          }
          
          fout<<endl;
          for(int i = 0; i < N; ++i) {
           while(!bck[i].empty())
            fout<<bck[i].front()+1<<' ' , bck[i].pop();
           fout<<endl;
          }*/
          
          for(vi::iterator p = cyc.begin(); p != cyc.end(); ++p) 
           fout<<*p + 1<<' ';
     }

    return 0;   
}