UVA 10054 - The Necklace ( 打印欧拉回路 )
题意
一种由彩色珠子组成的项链。每个珠子的两半由不同的颜色(最多50种颜色)组成。相邻的两个珠子在接触的地方颜色相同。现在有一些零碎的珠子,需要确定他们是否可以复原成完整的项链
思路
把每种颜色看成点, 每个珠子的两半连一条有向边, 转化为欧拉回路
后台数据很水, 连是否联通都不用判, 直接查每个颜色出现的次数是否为偶数即可. 重要的是欧拉回路的打印, dfs逆序输出就可以( 关于逆序打印 )
最难受的是第一次格式没处理好居然给我返的是WA, 害得我各种造数据纠结了半个多小时OAQ…
判某个条件是否会卡数据, 把那个条件对应写个死循环, 如果T了说明的确是这条判断有问题, 否则说明后台数据根本没用到这条判断
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#define mst(a) memset(a, 0, sizeof(a))
using namespace std;
int mrk[55], same[55];
int g[55][55];
const int INF = 0x3f3f3f3f;
int maxclr, minclr; //颜色最大数值
int n, all;
void init(){
mst(mrk);
mst(g);
mst(same);
maxclr = 0, minclr = INF;
}
bool judge(){
for( int i = minclr; i <= maxclr; i++ ){
if( mrk[i] % 2 != 0 ) return false;
if( same[i] && mrk[i] < 4 ) return false;
}
return true;
}
void euler(int x){
for( int i = minclr; i <= maxclr; i++ ){
if( g[x][i] ){
g[x][i]--;
g[i][x]--;
euler(i);
printf("%d %d\n",i, x);
}
}
return;
}
void print(){
for( int i = minclr; i <= maxclr; i++ )
euler(i);
}
int main()
{
int T, a, b;
scanf("%d",&T);
for( int kase = 1; kase <= T; kase++ ){
scanf("%d",&n);
init();
while( n-- ){
scanf("%d%d",&a, &b);
mrk[a]++, mrk[b]++;
maxclr = max(a, maxclr); maxclr = max(b, maxclr);
minclr = min(a, minclr); minclr = min(b, minclr);
if( a == b ) same[a]++;
g[a][b]++, g[b][a]++;
}
if( kase != 1 ) puts("");
printf("Case #%d\n",kase);
if( !judge() )
puts("some beads may be lost");
else print();
}
return 0;
}