1. 程式人生 > >Wine trading in Gergovia(歐拉回路)

Wine trading in Gergovia(歐拉回路)

【題意】
有一種彩色珠子連線成的項鍊,每個珠子的兩半由不同的顏色組成,相鄰兩個珠子在接觸的地方顏色要相同,現在有一些零碎的珠子,判斷它們是否可以復原成一條項鍊。

【思路】
把每種顏色看成一個結點,把每個珠子看成一條邊連線兩種顏色,那麼問題就轉換成了判斷圖中是否有歐拉回路的問題了。用dfs判聯通,用奇度頂點個數判是否存在歐拉回路,最後遞迴列印歐拉回路。

#include<bits/stdc++.h>
using namespace std;

const int maxn = 60;

int n, num;
int g[maxn][maxn];
bool
used[maxn]; bool have[maxn]; int degree[maxn]; void init() { memset(g, 0, sizeof(g)); memset(used, 0, sizeof(used)); memset(have, 0, sizeof(have)); memset(degree, 0, sizeof(degree)); } void dfs(int u) { used[u] = 1; for (int i = 1; i <= 50; ++i) { if (!used[i] && g[u][i]) dfs(i); } } void
euler(int u) {//列印以u為終點的歐拉回路 for (int i = 1; i <= 50; ++i) { if (g[u][i] > 0) { --g[u][i]; --g[i][u]; euler(i); printf("%d %d\n", i, u); } } } int main() { int t; scanf("%d", &t); for (int kase = 1; kase <= t; ++kase) { if
(kase != 1) printf("\n"); init(); scanf("%d", &n); for (int i = 1; i <= n; ++i) { int from, to; scanf("%d%d", &from, &to); have[from] = have[to] = 1; ++g[from][to]; ++g[to][from]; ++degree[to]; ++degree[from]; } //判聯通 int cnt = 0; for (int i = 1; i <= 50; ++i) { for (int j = 1; j <= 50; ++j) { if (!used[i] && g[i][j]) { ++cnt; dfs(i); } } } if (cnt > 1) { printf("Case #%d\nsome beads may be lost\n", kase); continue; } //判斷是否存在歐拉回路 bool ok = 1; for (int i = 1; i <= 50; ++i) { if (degree[i] & 1) { ok = 0; break; } } if (!ok) { printf("Case #%d\nsome beads may be lost\n", kase); continue; } //列印歐拉回路 printf("Case #%d\n", kase); for (int i = 1; i <= 50; ++i) if (have[i]) euler(i); } return 0; }