Pagini recente » Cod sursa (job #107158) | Cod sursa (job #275776) | Cod sursa (job #2957026) | Cod sursa (job #2519406) | Cod sursa (job #1356369)
#include <assert.h>
#include <stdio.h>
#define MAX_N 100000
#define MAX_M 500000
#define NIL -1
typedef struct {
int v, next;
int other; // pointer la celula-pereche din lista lui v
} adjCell;
adjCell l[2 * MAX_M]; // liste de adiacență alocate static
int adj[MAX_N]; // începutul listelor de adiacență
int st[MAX_M + 1], ss; // stiva nodurilor care încă mai au vecini
int degree[MAX_N];
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(FILE *f, int u) {
st[ss++] = u;
while (ss) {
u = st[ss - 1];
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) {
st[ss++] = l[adj[u]].v;
l[l[adj[u]].other].v = NIL; // marcăm celula-pereche ca folosită
adj[u] = l[adj[u]].next;
} else {
ss--;
if (ss) { // ca să nu duplicăm primul / ultimul nod
fprintf(f, "%d ", 1 + u);
}
}
}
}
int main(void) {
int n, m, 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(f, l[0].v); // Garantăm că începem parcurgerea dintr-un nod cu vecini
fprintf(f, "\n");
}
fclose(f);
}