UVa11054 欧拉回路

题意:有一种彩色珠子连成项链,每个珠子的两半由不同颜色组成,相邻的两个珠子接触的要相同颜色。是否有一个串法,如果有就输出顺序。

思路:如果把每个颜色建一个点,那么一个珠子就可以拆分成两个点,再加一条边,这样问题就转化成了求欧拉回路。

判断欧拉回路,首先要是连通的,再者是每个点都要有偶数个度。要连通可以使用并查集。

代码:

//http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=12&page=show_problem&problem=995
#include<stdio.h>
#include<string.h>
const int maxn = 80;
int map[maxn][maxn];
int deg[maxn];
int fa[maxn];
int n,maxv;
int find(int x)
{
	while(fa[x] != x)
		x = fa[x];
	return x;
}
void Union(int a,int b)
{
	int x = find(a);
	int y = find(b);
	if(x != y)
		fa[x] = y;
}
void DFS(int u)//欧拉回路
{
	for(int v =1;v<=maxv;v++)
	{
		if(map[u][v])
		{
			map[u][v]--;
			map[v][u]--;
//			printf("%d %d
",u,v);	
			DFS(v); //路径必须回溯时输出
			printf("%d %d
",v,u);
		}	
	}
}
bool degOK()
{
	for(int i=1;i<= maxv;i++)
		if(deg[i]%2)return false;
		return true;
}
inline int max(int a,int b)
{
	if(a > b)return a;
	return b;
}
void init()
{
	maxv=0;
	memset(map,0,sizeof(map));
	memset(deg,0,sizeof(deg));
	for(int i=0;i<maxn;i++)
		fa[i] = i;
}
int main()
{
	int t,i;
	int u,v;
	scanf("%d",&t);
	int cas = 0;
	while(t--)
	{
		init();
		scanf("%d",&n);
		for(i=1;i<= n;i++)
		{
			scanf("%d%d",&u,&v);
			map[u][v] ++;
			map[v][u] ++;
			deg[u]++;
			deg[v]++;
			Union(u,v); //判断图的连通性
			maxv = max(maxv,u);
			maxv = max(maxv,v);
		}
		int set = 0;
		for(i=1;i<=maxv;i++)
		{
			if(deg[i] && fa[i] == i)
				set++;
		}
		if(cas)  printf("
");
		printf("Case #%d
",++cas);
		if(set >1 || !degOK())
			printf("some beads may be lost
");
		else
			DFS(maxv);
	}
	return 0;
}

/*



2
5
1 2
2 3
3 4
4 5
5 6
5
2 1
2 2
3 4
3 1
2 4


  */
原文地址:https://www.cnblogs.com/BruceNoOne/p/3854301.html