Pagini recente » Cod sursa (job #572201) | Cod sursa (job #2669788) | Cod sursa (job #2466181) | Cod sursa (job #1098800) | Cod sursa (job #865692)
Cod sursa(job #865692)
//verific conexitatea si gradul fiecarui varf
//daca graful este eulerian, incep sa construiesc ciclul pornind
//de la un varf oarecare; atunci cand il inchid, il verific daca
//cuprinde fiecare muchie din graf; daca nu cuprinde, caut un varf
//de pe ciclu care sa aiba o muchie neprezenta in ciclu si pornind de la ea
//construiesc un nou ciclu; unesc cele doua cicluri si repet procesul.
//se poate aplica si pe multigraf, stergand din lista muchiilor pe cele
//incluse in ciclu (marcand 0)
#include <fstream>
#include <cstdlib>
using namespace std;
ifstream fin ("ciclueuler.in"); ofstream fout ("ciclueuler.out");
int *mat[101001], inc[101001], n, m, lg;
bool viz[101001];
struct nod {
int vf, urm;
}ciclu[501001];
void dfs (short int s) {
short int i;
viz[s]=1;
for (i=1; i<=mat[s][0]; ++i) if (!viz[mat[s][i]]) dfs(mat[s][i]);
}
void inserez (int unde, int vf, int urm) { ciclu[unde].vf=vf; ciclu[unde].urm=urm; }
int constr () {
int lg=1, a, b, i=1;
inserez(1, 1, 2); a=1;
while (mat[a][i]!=1) {
inserez(++lg, mat[a][i], lg+2);
b=mat[a][i];
mat[a][i]=0; --inc[a]; //sterg muchiile a-b, b-a
for (i=1; i<=mat[b][0]; ++i) if (mat[b][i]==a) { mat[b][i]=0; break; } --inc[b];
a=b; for (i=1; i<=mat[a][0]; ++i) if (mat[a][i]) break; //caut urmatoarea muchie
} ciclu[lg].urm=0; //inchid ciclul\
//sterg muchiile a-1, 1-a
mat[a][i]=0; --inc[a];
for (i=1; i<=mat[1][0]; ++i) if (mat[1][i]==a) { mat[1][i]=0; break; } --inc[1];
//returnez numarul de muchii
return lg;
}
void unesc (int s, int vf, int poz) {
int a, b, i, aux=ciclu[poz].urm;
ciclu[poz].urm=lg+1;
inserez(++lg, mat[s][vf], lg+2);
a=mat[s][vf];
//sterg muchiile s-a, a-s
mat[s][vf]=0; --inc[s];
for (i=1; i<=mat[a][0]; ++i) if (mat[a][i]==s) { mat[a][i]=0; break; } --inc[a];
for (i=1; i<=mat[a][0]; ++i) if (mat[a][i]) break; //caut urmatoarea muchie din a din afara
while (mat[a][i]!=s) {
inserez(++lg, mat[a][i], lg+2);
b=mat[a][i];
mat[a][i]=0; --inc[a]; //sterg muchiile a-b, b-a
for (i=1; i<=mat[b][0]; ++i) if (mat[b][i]==a) { mat[b][i]=0; break; } --inc[b];
a=b; for (i=1; i<=mat[a][0]; ++i) if (mat[a][i]) break;
}
inserez(++lg, s, lg+2); //inchid ciclul
mat[a][i]=0; --inc[a]; //sterg muchiile a-s, s-a
for (i=1; i<=mat[s][0]; ++i) if (mat[s][i]==a) { mat[s][i]=0; break; } --inc[s];
ciclu[lg].urm=aux; //introduc ciclul in ciclu
}
int main()
{
int i, a, b, j, poz; bool par=1;
fin>>n>>m;
for (i=1; i<=n; ++i) { mat[i]=(int*)realloc(mat[i], sizeof(int)); mat[i][0]=0; }
for (i=1; i<=m; ++i) { //citesc multigraful
fin>>a>>b;
++mat[a][0]; mat[a]=(int*)realloc(mat[a], sizeof(int)*(mat[a][0]+1)); mat[a][mat[a][0]]=b; ++inc[a];
++mat[b][0]; mat[b]=(int*)realloc(mat[b], sizeof(int)*(mat[b][0]+1)); mat[b][mat[b][0]]=a; ++inc[b];
}
for (i=1; i<=n && par; ++i) if (mat[i][0]%2==1) par=0; //verific gradul fiecarui varf
if (par) { //verific conexitatea
dfs(1);
for (i=1; i<=n && par; ++i) if (!viz[i]) par=0;
}
if (par) { //graful este eulerian
lg=constr();
if (lg!=m) { i=1; while (!inc[ciclu[i].vf] && i<=lg) ++i; }
while (i<=lg && lg!=m) {//nu am determinat inca ciclul eulerian - i mai are muchii incidente in afara
for (j=1; j<=mat[ciclu[i].vf][0]; ++j) if (mat[ciclu[i].vf][j]) break; //caut prima muchie din afara
unesc(ciclu[i].vf, j, i);
if (lg!=m) { i=1; while (!inc[ciclu[i].vf] && i<=lg) ++i; }
}
fout<<1<<' '; poz=ciclu[1].urm;
while (poz) {
fout<<ciclu[poz].vf<<' ';
poz=ciclu[poz].urm;
}
fout<<'\n';
}
else fout<<-1<<'\n'; //graful nu este eulerian
fout.close();
return 0;
}