Uva 10054 - The Necklace(欧拉回路)
题目链接 https://vjudge.net/problem/UVA-10054
【题意】
有一种彩色珠子连接成的项链,每个珠子的两半由不同的颜色组成,相邻两个珠子在接触的地方颜色要相同,现在有一些零碎的珠子,判断它们是否可以复原成一条项链。
【思路】
把每种颜色看成一个结点,把每个珠子看成一条边连接两种颜色,那么问题就转换成了判断图中是否有欧拉回路的问题了。用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;
}