Cod sursa(job #2197617)

Utilizator pitradaPit-Rada Ionel-Vasile pitrada Data 22 aprilie 2018 16:25:57
Problema Ciclu Eulerian Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.92 kb
#include <fstream>
#define nmax 100002
#define mmax 500002
using namespace std;
struct graf_neorientat{
    int n,m,grad[nmax+2];
    ///pentru pastrarea muchiilor
    struct muchie{int x,y;}L[mmax+2];
    ///pentru eliminarea muchiilor parcurse
    bool vizm[mmax+2],viz[nmax+2];
///pentru etichetelor muchiilor corespunzatoare vecinilor
    int Start[nmax+2];///accesul la primul vecin
    struct vecin{int pozm,urm;}T[2*mmax+2];
    ///pentru pastrarea nodurilor ciclului
    int E[mmax+2],Stiva[mmax+2],vfs;
    void citire(){
        ifstream  fin("ciclueuler.in");
        int i,j,k,r;
        fin>>n>>m;
        for(k=1;k<=n;k++){
            Start[k]=0;grad[k]=0;
        }
        r=0;
        for(k=1;k<=m;k++){
            fin>>i>>j;
	       L[k]={i,j};
            vizm[k]=false; grad[i]++; grad[j]++;
            r++; T[r]={k,Start[i]}; Start[i]=r;
            r++; T[r]={k,Start[j]}; Start[j]=r;
        }
        fin.close();
    }
    void dfs(int vf){
        viz[vf]=1;
        for(int i=Start[vf];i;i=T[i].urm){
             int p=T[i].pozm;
             int z=L[p].x+L[p].y-vf;
             if(viz[z]==0)dfs(z);
        }
    }
    void ciclu_eulerian(){
        ofstream fout("ciclueuler.out");
        int k,r,p,q;
        ///verific daca graful este eulerian
        ///trebuie ca subgraful varfurilor neizolate sa fie conex si
        ///sa nu existe varfuri de grad impar
        for(k=1;k<=n;k++)viz[k]=0;
        p=0;q=0;r=0;
        for(k=1;k<=n;k++){
            if(grad[k] && viz[k]==0){
                p++;///numar componentele conexe cu varfuri neizolate
		     if(p>1)break;
                dfs(k);
            }
            if(grad[k]%2==1){
                q++;///exista grad impar
                break;
            }
            if(grad[k])r++;
        }
        if(p>1 || q>0 || r==0){fout<<-1;return;}
///neconex sau exista grad impar sau toate varfurile sunt izolate

        ///graful este eulerian
        r=0;///E este lista vida
        k=1;while(k<=n && grad[k]==0)k++;///gasim un nod neizolat
        vfs=1;Stiva[1]=k;///pentru pornire depunem in stiva varful k
        while(vfs){
            p=Stiva[vfs];
            if(grad[p]==0){
                E[++r]=p; vfs--;
     ///adaugam p in lista E si scoatem p din stiva
            }
            else{
                ///cautam primul vecin de pe muchie nevizitata
                k=Start[p];
                while(vizm[T[k].pozm])k=T[k].urm;
                q=L[T[k].pozm].x+L[T[k].pozm].y-p;
                ///stergem muchia
                grad[p]--; grad[q]--;
                vizm[T[k].pozm]=true;
                Start[p]=T[k].urm;
                ///adaugam q in stiva
                Stiva[++vfs]=q;
            }
        }
        ///scriem ciclul
        for(k=1;k<r;k++) fout<<E[k]<<" ";
        fout.close();
    }
} G;
int main(){
    G.citire();    G.ciclu_eulerian();    return 0;
}