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;
}
// 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;
}
相关文章推荐
- web验证码实现
- Jetson TK1
- hdu 5305 Friends(2015多校第二场第6题)记忆化搜索
- 重载,覆盖,隐藏
- H264编码 封装成MP4格式 视频流 RTP封包
- E - QS Network - zoj 1586(简单)
- Openssl s_client命令
- 读《代码整洁之道》前四章浅显印象 和 我所见的不整洁代码引以为戒
- 近期的一点感悟
- Android之自定义checkbox样式
- 1059. Prime Factors (25)
- uva673_平衡的括号(网上写的好麻烦。。)
- Android:TabHost实现Tab切换
- 多重部分和问题
- 从AdventureWorks学习数据库建模——实体分析
- 二叉树的遍历
- web中验证码实现
- 约瑟夫问题
- oracle之连接查询及子查询举例
- Openssl s_server命令