正确的建模很重要,如果选取珠子为顶点则问题转换为哈密顿回路问题,而则个是个指数级的问题,但是如果选取珠子
为边,则问题转换为欧拉回路问题,这个可以在O(E)的时间内解决。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int size = 1000 + 10;
const int color_size = 50 + 10;
int u[size] , v[size];
int f[size] , vis[size];
int first[color_size] , deg[color_size];
int Next[size * 2] , Val[size * 2][2];
void dfs(int x)
{
vis[x] = 1;
for(int y = first[x] ; y != -1 ; y = Next[y])
{
if(!vis[Val[y][0]])dfs(Val[y][0]);
}
}
int euler(int x)
{
if(deg[x] % 2) return 0;
for(int y = first[x] ; y != -1 ; y = Next[y])
{
if(!vis[Val[y][1]])
{
vis[Val[y][1]] = 1;
int r = euler(Val[y][0]);
if(!r) return 0;
printf("%d %d\n" , Val[y][0] , x);
}
}
return 1;
}
int main()
{
int T , n , cnt = 1;
scanf("%d" , &T);
while(T-- > 0)
{
scanf("%d" , &n);
int cur = 0;
memset(first , -1 , sizeof(first));
memset(deg , 0 , sizeof(deg));
for(int i = 0 ; i < n ; ++i)
{
scanf("%d%d" , &u[i] , &v[i]);
Next[cur] = first[u[i]];
Val[cur][0] = v[i];
Val[cur][1] = i;
first[u[i]] = cur++;
++deg[u[i]];
Next[cur] = first[v[i]];
Val[cur][0] = u[i];
Val[cur][1] = i;
first[v[i]] = cur++;
++deg[v[i]];
}
int block = 0;
memset(vis , 0 , sizeof(vis));
for(int i = 0 ; i < color_size ; ++i)
{
if(first[i] != - 1 && !vis[i])
{
++block;
dfs(i);
}
}
printf("Case #%d\n" , cnt++);
int ok = 0;
memset(vis , 0 , sizeof(vis));
if(block == 1)
{
ok = euler(u[0]);
}
if(!ok)
{
printf("some beads may be lost\n");
}
if(T>0) printf("\n");
}
return 0;
}