欧拉回路和欧拉路径
几个入门的题目:
hdu 1878
判定一个图是否存在欧拉回路。
直接判断图是否连通和每个点的度数是否为偶数就行了。(可用并查集判断连通,也可以用dfs)
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int maxn = 1100; int in[maxn]; int F[maxn]; void init() { memset(F, -1, sizeof(F)); } int find(int x) { if (F[x] == -1) return x; return F[x] = find(F[x]); } void Union(int x, int y) { int tx = find(x); int ty = find(y); if (tx != ty) F[tx] = ty; } int main() { int n, m; while (~scanf("%d", &n) && n) { memset(in, 0, sizeof(in)); scanf("%d", &m); int u, v; init(); for (int i = 1; i <= m; i++) { scanf("%d %d", &u, &v); Union(u, v); ++in[u]; ++in[v]; } int flag = 1; for (int i = 1; i <= n; i++) { if (in[i] % 2) { flag = 0; break; } } if (flag) { for (int i = 2; i <= n; i++) { if (find(i) != find(1)) { flag = 0; break; } } } printf("%d\n", flag); } return 0; }
poj 1041
求欧拉回路。
dfs回溯的时候求,因为是个回路,所以要在回溯的时候加到 答案 数组当中
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 2000; struct Edge { int to, next, id; }edge[5000000]; int tot; int head[maxn]; int in[maxn]; int F[maxn]; void init() { tot = 0; memset(head, -1, sizeof(head)); memset(in, 0, sizeof(in)); memset(F, -1, sizeof(F)); } void addedge(int u, int v, int id) { edge[tot].to = v; edge[tot].id = id; edge[tot].next = head[u]; head[u] = tot++; } int find(int x) { if (F[x] == -1) return x; return F[x] = find(F[x]); } void Union(int x, int y) { int tx = find(x); int ty = find(y); if (tx != ty) F[tx] = ty; } int n; bool check() { for (int i = 1; i <= n; i++) if (in[i] & 1 || in[i] == 0) return false; for (int i = 2; i <= n; i++) if (find(i) != find(1)) return false; return true; } int S[5000000]; bool vis[5000000]; int top; void dfs(int u) { for (int i = head[u]; i != -1; i = edge[i].next) { if (vis[i]) continue; vis[i] = true; vis[i ^ 1] = true; dfs(edge[i].to); S[top++] = i; } } int main() { int u, v, id; while (~scanf("%d %d", &u, &v)) { if (u == 0 && v == 0) break; scanf("%d", &id); n = -1; init(); addedge(u, v, id); addedge(v, u, id); Union(u, v); n = max(n, u); n = max(n, v); ++in[u]; ++in[v]; while (~scanf("%d %d", &u, &v)) { if (u == 0 && v == 0) break; scanf("%d", &id); addedge(u, v, id); addedge(v, u, id); Union(u, v); n = max(n, u); n = max(n, v); ++in[u]; ++in[v]; } if (!check()) puts("Round trip does not exist."); else { top = 0; memset(vis, false, sizeof(vis)); dfs(1); for (int i = 0; i < top; i++) printf("%d%c", edge[S[i]].id, i == top - 1 ? '\n' : ' '); } } return 0; }
uva10054
求欧拉回路。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 2000; struct Edge { int to, next; }edge[1000100]; int tot; int head[maxn]; int in[maxn]; int F[maxn]; void init() { tot = 0; memset(head, -1, sizeof(head)); memset(in, 0, sizeof(in)); memset(F, -1, sizeof(F)); } void addedge(int u, int v) { edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++; } int find(int x) { if (F[x] == -1) return x; return F[x] = find(F[x]); } void Union(int x, int y) { int tx = find(x); int ty = find(y); if (tx != ty) F[tx] = ty; } int n; bool color[100]; int st; bool check() { for (int i = 1; i <= n; i++) if (color[i]) if (in[i] & 1 || in[i] == 0) return false; for (int i = 1; i <= n; i++) if (color[i]) if (find(i) != find(st)) return false; return true; } Edge ans[1000010]; bool vis[1000010]; int top; void dfs(int u) { for (int i = head[u]; i != -1; i = edge[i].next) { if (vis[i]) continue; vis[i] = true; vis[i ^ 1] = true; dfs(edge[i].to); ans[top].to = u; ans[top++].next = edge[i].to; } } int main() { int T, kase = 0; scanf("%d", &T); while (T--) { memset(color, false, sizeof(color)); init(); int m; scanf("%d", &m); int u, v; n = -1; for (int i = 0; i < m; i++) { scanf("%d %d", &u, &v); n = max(n, u); n = max(n, v); addedge(u, v); addedge(v, u); Union(u, v); ++in[u]; ++in[v]; color[u] = color[v] = true; } st = u; if (!check()) printf("Case #%d\nsome beads may be lost\n", ++kase); else { top = 0; memset(vis, false, sizeof(vis)); dfs(st); printf("Case #%d\n", ++kase); for (int i = top - 1; i >= 0; i--) printf("%d %d\n", ans[i].to, ans[i].next); } if (T) printf("\n"); } return 0; }