Pagini recente » Cod sursa (job #2385068) | Cod sursa (job #2056387) | Profil Kopac13 | Cod sursa (job #1804864) | Cod sursa (job #1356366)
#include <assert.h>
#include <stdio.h>
#define MAX_N 100000
#define MAX_M 500000
#define NIL -1
typedef struct {
int v;
int other; // pointer la celula-pereche din lista lui v
int next;
} adjCell;
typedef struct {
int u, next;
} tourCell;
adjCell l[2 * MAX_M]; // liste de adiacență alocate static
int adj[MAX_N]; // începutul listelor de adiacență
tourCell t[MAX_M + 1]; // lista pentru ciclul eulerian alocată static
int tPtr; // prima celulă disponibilă
int degree[MAX_N];
int n, m;
void addChild(int u, int v, int cell, int other) {
l[cell].v = v;
l[cell].other = other;
l[cell].next = adj[u];
adj[u] = cell;
degree[u]++;
}
void euler(int u) {
while (adj[u] != NIL) {
int v = l[adj[u]].v;
if (v != NIL) {
t[tPtr].next = tPtr + 1;
t[tPtr++].u = v;
l[l[adj[u]].other].v = NIL; // marcăm celula-pereche ca folosită
adj[u] = l[adj[u]].next;
u = v;
} else {
adj[u] = l[adj[u]].next;
}
}
t[tPtr - 1].next = NIL;
}
int main(void) {
int u, v;
FILE *f = fopen("ciclueuler.in", "r");
assert(fscanf(f, "%d%d", &n, &m) == 2);
for (int i = 0; i < n; i++) {
adj[i] = NIL;
}
for (int i = 0; i < m; i++) {
assert(fscanf(f, "%d%d", &u, &v) == 2);
u--;
v--;
addChild(u, v, 2 * i, 2 * i + 1);
addChild(v, u, 2 * i + 1, 2 * i);
}
fclose(f);
int odd = 0;
while ((odd < n) && ((degree[odd] & 1) == 0)) {
odd++;
}
f = fopen("ciclueuler.out", "w");
if (odd < n) {
fprintf(f, "-1\n");
} else {
euler(l[0].v); // Garantăm că începem parcurgerea dintr-un nod cu vecini
// Iterăm prin acest prim ciclu și inserăm alte cicluri găsite
int i = 0;
while (i != NIL) {
int u = t[i].u;
fprintf(f, "%d ", 1 + u);
while ((adj[u] != NIL) && (l[adj[u]].v == NIL)) {
adj[u] = l[adj[u]].next; // sărim peste muchiile folosite deja
}
if (adj[u] != NIL) {
int tPtrSave = tPtr;
euler(u);
t[tPtr - 1].next = t[i].next;
t[i].next = tPtrSave;
}
i = t[i].next;
}
fprintf(f, "\n");
}
fclose(f);
}