大意略。
思路:无向图的欧拉回路,其中有重复的数据,先判连通,然后判是否有奇数度的点,然后输出欧拉回路,函数有了小变化。
void euler(int u) //有重复数据 { for(int v = 1; v <= maxn; v++) if(G[u][v]) { --G[u][v], --G[v][u]; euler(v); printf("%d %d\n", v, u); } } void euler(int u) //无重复数据 { for(int v = 1; v <= maxn; v++) if(G[u][v] && !vis[u][v]) { vis[u][v] = vis[v][u] = 1; euler(v); printf("%d %d\n", u, v); } }
#include <iostream> #include <cstdlib> #include <cstdio> #include <string> #include <cstring> using namespace std; const int maxn = 51; int G[maxn][maxn]; int de[maxn]; int p[maxn]; int vis[maxn][maxn]; void init() { memset(G, 0, sizeof(G)); memset(de, 0, sizeof(de)); for(int i = 1; i <= maxn; i++) p[i] = i; } void euler(int u) { for(int v = 1; v <= maxn; v++) if(G[u][v]) { --G[u][v], --G[v][u]; euler(v); printf("%d %d\n", v, u); } } void euler(int u) { for(int v = 1; v <= maxn; v++) if(G[u][v] && !vis[u][v]) { vis[u][v] = vis[v][u] = 1; euler(v); printf("%d %d\n", u, v); } } int find(int x) { return x == p[x]? x : p[x] = find(p[x]); } void Union(int a, int b) { int x = find(a), y = find(b); if(x != y) p[x] = y; } int check() //判连通 { int count = 0; for(int i = 1; i <= maxn; i++) { if(de[i] & 1) return 0; if(de[i] && p[i] == i) count++; } return count == 1; } void read_case() { init(); int n; scanf("%d", &n); for(int i = 0; i < n; i++) { int u, v; scanf("%d%d", &u, &v); G[u][v]++, G[v][u]++; de[u]++, de[v]++; Union(u, v); } } void solve() { read_case(); if(!check()) printf("some beads may be lost\n"); else { for(int i = 1; i <= maxn; i++) if(de[i]) { euler(i); break; } } } int main() { int T, times = 0; scanf("%d", &T); while(T--) { printf("Case #%d\n", ++times); solve(); printf("\n"); } return 0; }