您的位置:首页 > 其它

uva 10054--The Necklace

2015-07-24 20:39 525 查看
//
// main.cpp
// uva 10054 - The Necklace
//
// Created by XD on 15/7/21.
// Copyright (c) 2015年 XD. All rights reserved.
//
#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <vector>
#include <string.h>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <cstdio>
using namespacestd ;

//用来寻找路径

int visit[55][55] ;
int g[55][55];
int d[55] ;
struct edge{
int u ;
int v ;
};

//用来存储路径

stack<edge> eulerpath ;

//欧拉回路算法,使用递归的思想
void euler(int s)
{

for (int i = 1 ; i < 51 ; i++) {
if (g[s][i]) {
g[s][i]--;g[i][s]--;
edge temp ; temp.u = s ; temp.v = i ;
/*以下两步顺序很重要,先使用递归查找所有的圈,这样就可以找到欧拉路径
以下是详细解释
思想是先将在将来访问到的节点可能的圈给压入栈中,然后就可以将当前的边压入栈中,这样根据栈的先进后出的特点,就可以直接打印出欧拉路径,当然也可以使用数组,因为这是无向图,所以无方向,但是对于有向图,则用栈(主要省去了不必要的逆序打印的麻烦)
*/
euler(i) ;
eulerpath.push(temp) ;
}
}
}

//并查集判断连通性
int p[55] ;
int r[55] ;
void init()
{
for (int i = 0 ; i < 51; i++) {
p[i]= i ;
r[i] = 0 ;
}
}
//并查集的三个函数,使用了rank(秩,算法导论书上的),和路径压缩
int find_set(int x)
{

if (p[x]!=x) {
p[x] =find_set(p[x]) ;
}

returnp[x] ;
}

void link(int x ,int y )
{
if (r[x] <r[y]) {
p[x] =p[y] ;
}
else
{
p[y] = x ;
if (r[x] ==r[y]) {
r[x] += 1 ;
}
}
}

void UnionSet(int x ,int y)
{
link(find_set(x) ,find_set(y)) ;
}

//
set<int> node ;

int main(int argc,const char * argv[]) {
int casenum ;
scanf("%d" ,&casenum) ;
int u , v ;
int n ;
int j = 0;

while (casenum--) {
while (!eulerpath.empty()) {
eulerpath.pop() ;
}
init() ;
memset(g, 0,sizeof(g)) ;
memset(visit, 0,sizeof(visit)) ;
memset(p, 0,sizeof(p)) ;
memset(r,0,sizeof(r)) ;
node.clear() ;
memset(d, 0,sizeof(d)) ;
scanf("%d" ,&n) ;
for (int i = 0 ; i < n; i++) {
scanf("%d%d" ,&u,&v) ;
UnionSet(u, v) ;
node.insert(u) ;node.insert(v) ;
g[u][v]++ ;g[v][u]++; ;
d[u]++ ;d[v]++ ;
}

int flag = -1 ;
int start =0;
for (set<int >::iterator it = node.begin() ; it!=node.end(); it++) {
start = *it ;
if (d[*it]%2==1) {
flag = -2 ;
break ;
}
if (flag==-1) {
flag = find_set(*it) ;
}
else{
if (flag!=find_set(*it)) {
flag = -2 ;
break ;
}
}
}

printf("Case #%d\n" , ++j) ;
if (flag ==-2) {
printf("some beads may be lost\n") ;
}
else{
euler(start) ;
while (!eulerpath.empty()) {
edge temp =eulerpath.top() ;eulerpath.pop() ;
printf("%d %d\n" ,temp.u,temp.v) ;
}
}

if (casenum> 0 ) {
printf("\n") ;
}
}
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: