http://acm.sdut.edu.cn:8080/vjudge/contest/view.action?cid=116#problem/C
题意:有一种由彩色珠子连成的项链,每个珠子的两半由不同颜色(由1~50表示各种颜色)组成,相邻两个珠子在接触的地方颜色相同。现在给你一些零碎的珠子,确认他们是否可以复原成完整的项链。
思路:把每个珠子的两半颜色看成节点,它们之间建一条无向边。转化为n条边能否组成一个欧拉回路问题。
欧拉回路即给定无孤立节点图G,若存在一条回路,经过图中每边一次且仅一次。由定义知,欧拉回路存在首先图的连通的并且每个节点的度数为偶数。在这个基础上通过dfs打印路径。
据说这道题数据都是连通的,所以没判断是否连通。
建图时注意,可以有重边。
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stack>
#define LL long long
#define _LL __int64
using namespace std;
//const int INF = 0x3f3f3f3f;
int map[55][55];
int deg[55];
stack < pair<int,int> > st;
void dfs(int u)
{
for(int i = 1; i <= 50; i++)
{
if(map[u][i])
{
map[u][i]--;
map[i][u]--;
dfs(i);
//printf("%d %d\n",i,u); //打印路径时,可以直接逆序输出
st.push(make_pair(u,i));//也可以先放入栈中最后输出
}
}
}
int main()
{
int test;
int n,u,v;
int flag,start;
scanf("%d",&test);
for(int item = 1; item <= test; item++)
{
memset(map,0,sizeof(map));
memset(deg,0,sizeof(deg));
while(!st.empty()) st.pop();
flag = 1;
scanf("%d",&n);
for(int i = 1; i <= n; i++)
{
scanf("%d %d",&u,&v);
map[u][v]++;
map[v][u]++;
deg[u]++;
deg[v]++;
}
int maxdeg = -1;
for(int i = 1; i <= 50; i++)
{
if(deg[i]&1)
{
flag = 0;
break;
}
else
{
if(maxdeg < deg[i])
{
maxdeg = deg[i];
start = i;
}
}
}
if(item != 1)
printf("\n");
printf("Case #%d\n",item);
if(!flag)
printf("some beads may be lost\n");
else
{
dfs(start);
while(!st.empty())
{
pair<int,int> u = st.top();
st.pop();
printf("%d %d\n",u.first,u.second);
}
}
}
return 0;
}