Pagini recente » Cod sursa (job #764505) | Cod sursa (job #1002134) | tema | Cod sursa (job #908015) | Cod sursa (job #882120)
Cod sursa(job #882120)
#include <fstream>
using namespace std;
ifstream fin("graf_eulerian.in");
ofstream fout("graf_eulerian.out");
struct Nod
{
int vf;
struct Nod * urm;
};
typedef struct Nod * Lista;
int n, m;
int d[1000];
bool viz[1000];
bool g[1000][1000];
Lista c1, c2, sfc1, sfc2;
void citire();
void dfs(int x);
void det_eulerian();
bool conex();
int gradepare();
void afisare_ciclu();
int ciclu(int, Lista&, Lista&);
int main()
{
citire();
if(conex() && gradepare())
{
fout<<"Eulerian\n";
det_eulerian();
afisare_ciclu();
}
else fout<<"Neeulerian\n";
}
void citire()
{
int i, x, y;
fin>>n>>m;
for(i=1; i<=m; i++)
{
fin>>x>>y;
g[x][y]=g[y][x]=true;
d[x]++;
d[y]++;
}
}
void dfs(int x)
{
int i;
viz[x]=true;
for(i=1; i<=n; i++)
if(viz[i]==0 && g[x][i]==1)
dfs(i);
}
bool conex()
{
int x, i;
//caut un varf neizolat
for(x=1; x<=n && !d[x]; x++);
if(x>n) return 1;
//x este vf neizolat
dfs(x);
for(i=1; i<=n; i++) //verific daca au mai ramas varfuri nevizitate si neizolate
if(!viz[i] && d[i]) return 0;
return 1;
}
int gradepare()
{
int i;
for(i=1; i<=n; i++)
if(d[i]%2) return 0;
return 1;
}
void det_eulerian()
{
int x, nr2, total;
Lista p, q;
//caut un varf cu gradul nenul
for(x=1; x<=n && !d[x]; x++);
//x are gradul nenul
total=ciclu(x, c1, sfc1);
while(total<m)
{
//caut pe c1 un vf cu gradul nenul
for(p=c1; !d[p->vf]; p=p->urm);
//acum p indica in vf cu gradul nenul
//contsruiesc al doilea ciclu
nr2=ciclu(p->vf, c2, sfc2);
//reunesc ciclul c1 cu ciclul c2
q=p->urm;
p->urm=c2->urm;
sfc2->urm=q;
total+=nr2;
}
}
int ciclu(int x, Lista& c, Lista& sfc)
{
Lista p;
int y, uvf, lg=0; //uvf-ult nod din lista
//incep ciclul cu vf x
//aloc memorie pt un nod
p=new Nod;
p->vf=x;
p->urm=NULL;
c=sfc=p; //el este singurul, primul, ultimul
do
{
//caut y, un varf adiacent cu ultimul varf din lista
uvf=sfc->vf;
//parcurg linia uvf pana dau de un y adiacent cu el
for(y=1; !g[uvf][y]; y++)
//adaug muchia [uvf, y] in ciclul eulerian
//aloc memorie pt un nou vf
p=new Nod;
p->vf=y;
p->urm=NULL;
//il adaug la sfarsitul ciclului
sfc->urm=p;
sfc=p;
lg++;
//am folosit aceasta muchie si o elimin din graf
g[uvf][y]=g[y][uvf]=false;
d[y]--;
d[uvf]--;
}
while(y!=x);
return lg;
}
void afisare_ciclu()
{
Lista p;
for(p=c1; p; p=p->urm)
fout<<p->vf<<' ';
fout<<'\n';
}