首页 > 代码库 > UVa11054 欧拉回路

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\n",u,v);				DFS(v); //路径必须回溯时输出			printf("%d %d\n",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("\n");		printf("Case #%d\n",++cas);		if(set >1 || !degOK())			printf("some beads may be lost\n");		else			DFS(maxv);	}	return 0;}/*251 22 33 44 55 652 12 23 43 12 4  */