本文链接:http://www.cnblogs.com/Ash-ly/p/5405904.html

题意:

  妹妹有一条项链,这条项链由许多珠子串在一起组成,珠子是彩色的,两个连续的珠子的交汇点颜色相同,也就是对于相邻的两个珠子来说,前一个珠子的末端颜色和后一个珠子的首端颜色相同。有一天,项链断了,珠子洒落了一地,到处都是,妹妹使出浑身解数把地板上能看到的珠子(5-1000)都捡了起来,但是不确定是否收集齐了。给你他妹妹收集的珠子的两端的颜色编号(1 - 50),让你判断是否收集齐了。

思路:

  把颜色看成点,把一个珠子看成一个无向边,则问题有解,当且仅当图中存在欧拉回路。于是先判断由题意构建出来的无向图是否存在欧拉回路,无向图能否构建出来欧拉回路需要满足两个条件:

1:底图连通,可以用并查集或者DFS判断,这里利用并查集了。

2:不存在度数为奇数的点。

  判断完成后,利用DFS遍历整个图,每访问一个点就把这个点压入栈中,回溯时弹出来当前点并记录下来。随后得到的就是欧拉回路的点的顺序,连续的两个点就是问题需要输出的边。

代码:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
using namespace std; const int maxV = ;
const int maxE = ;
int degree[maxV + ];
int pre[maxV + ];
int head[maxV + ];
int vis[maxE * + ];
int E, V; struct EdgeNode
{
int to;
int next;
}edges[ * maxE + ]; void initPre()
{
for(int i = ; i <= maxV; i++)pre[i] = i;
} int Find(int x)
{
return x == pre[x] ? x : pre[x] = Find(pre[x]);
} void mix(int x, int y)
{
int fx = Find(x);
int fy = Find(y);
if(fx != fy) pre[fx] = fy;
} int isEuler()
{
for(int i = ; i <= maxV; i++)
if(degree[i] & ) return ;
return ;
} int isConnct()
{
int cnt = ;
for(int i = ; i <= maxV; i++)
if(degree[i] && pre[i] == i) cnt++;
if(cnt == ) return ;
return ;
} stack<int> eu;
int ans[maxE + ];
int len;
void eulerDFS(int now)
{
eu.push(now);
for(int k = head[now]; k != -; k = edges[k].next)
{
if(!vis[k])
{
vis[k] = ;
if(k & ) vis[k + ] = ;
else vis[k - ] = ;
eulerDFS(edges[k].to);
}
}
ans[++len] = eu.top();//储存欧拉回路点的序列
eu.pop();
} int main()
{
//freopen("in.txt", "r", stdin);
int T;
scanf("%d", &T);
int kas = ;
while(T--)
{
scanf("%d", &E);
memset(degree, , sizeof(degree));
memset(edges, , sizeof(EdgeNode));
memset(head, -, sizeof(head));
initPre();
int st = ;//默认路径起点
for(int i = ; i <= E; i++)
{
int u, v;
scanf("%d%d", &u, &v);
edges[ * i - ].to = v;//链式前向星存储无向图的边需正反各存一次
edges[ * i - ].next = head[u];
head[u] = * i - ;
edges[ * i].to = u;
edges[ * i].next = head[v];
head[v] = * i;
degree[u]++;
degree[v]++;
mix(u, v);
st = min(st, min(u, v));
}
printf("Case #%d\n", ++kas);
if(isConnct() && isEuler())
{
memset(vis, , sizeof(vis));
memset(ans, , sizeof(ans));
len = ;
eulerDFS(st);
for(int i = ; i < len; i++)//两个相邻的点构成一条边
printf("%d %d\n", ans[i], ans[i + ]);
}
else
printf("some beads may be lost\n");
if(T)printf("\n");
}
return ;
}

(PS:不只是题意没理解透还是什么,如果妹妹没捡起来的刚好也构成了欧拉回路,那么岂不是还是没收集齐嘛,不过等串起来应该会发现的 (逃......)

UVA 10054 The Necklace (无向图的欧拉回路)的更多相关文章

  1. UVa 10054 The Necklace(无向图欧拉回路)

    My little sister had a beautiful necklace made of colorful beads. Two successive beads in the neckla ...

  2. uva 10054 The Necklace 拼项链 欧拉回路基础应用

    昨天做了道水题,今天这题是比较水的应用. 给出n个项链的珠子,珠子的两端有两种颜色,项链上相邻的珠子要颜色匹配,判断能不能拼凑成一天项链. 是挺水的,但是一开始我把整个项链看成一个点,然后用dfs去找 ...

  3. UVa 10054 The Necklace BFS+建模欧拉回路

    算法指南 主要就是建立欧拉回路 #include <stdio.h> #include <string.h> #include <iostream> #includ ...

  4. UVA 10054 The Necklace 转化成欧拉回路

    题意比较简单,给你n个项链碎片,每个碎片的两半各有一种颜色,最后要把这n个碎片串成一个项链,要求就是相邻碎片必须是同种颜色挨着. 看了下碎片总共有1000个,颜色有50种,瞬间觉得普通方法是无法在可控 ...

  5. UVA 10054 The Necklace(欧拉回路,打印路径)

    题目链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  6. uva 10054 The Necklace(欧拉回路)

    The Necklace  My little sister had a beautiful necklace made of colorful beads. Two successive beads ...

  7. UVA 10054 the necklace 欧拉回路

    有n个珠子,每颗珠子有左右两边两种颜色,颜色有1~50种,问你能不能把这些珠子按照相接的地方颜色相同串成一个环. 可以认为有50个点,用n条边它们相连,问你能不能找出包含所有边的欧拉回路 首先判断是否 ...

  8. UVa 10054 The Necklace【欧拉回路】

    题意:给出n个珠子,珠子颜色分为两半,分别用1到50之间的数字表示, 现在给出n个珠子分别的颜色,问是否能够串成一个环.即为首尾相连,成为一个回路 判断是否构成一个环,即判断是否为欧拉回路,只需要判断 ...

  9. 【欧拉回路】UVA - 10054 The Necklace

    题目大意: 一个环被切割成了n个小块,每个小块有头尾两个关键字,表示颜色. 目标是判断给出的n个小块能否重构成环,能则输出一种可行解(按重构次序输出n个色块的头尾颜色).反之输出“some beads ...

随机推荐

  1. Pascal小游戏 井字棋

    一个很经典的井字棋游戏 Pascal源码Chaobs奉上 注意:1.有的FP版本不支持汉语,将会出现乱码.2.别想赢电脑了,平手不错了. 井字过三关: program TicTacToe; uses ...

  2. javascript 数组的常用方法总结

    前言 主要讨论一下数组的方法,     1.splice和slice的区别     2.pop和push     3.shift和unshift     4.join     5.forEach(es ...

  3. canda 常用命令

    1.获取版本 conda -V conda --version 2.获取帮助 conda -h conda --help 查看某一命令的帮助 conda install -h conda instal ...

  4. (笔记) RealTimeRender[实时渲染] C2

    @author: 白袍小道 @来源:RealTime Render @建议书籍:龙书.RealTimeR第四版.GPUGem和PRO (来源:暗影不解释) 引点 这一章关注的管线中的管道功能,而非实现 ...

  5. ./configure, make, sudo make install 的含义

    一般编译安装会用到. 将压缩包example.tar.gz解压到onePackage下example, 在onePackage下新建install文件夹. 在终端中执行 1) 配置sudo ./con ...

  6. 批量部署ssh免密登陆

    #!/bin/bash#set -xservers="10.254.192.xx10.254.192.xx10.254.192.xx"passwd="xxxxxxxx&q ...

  7. Android Service完全解析

    Service的基本用法 1.新建一个Android项目,新建一个MyService继承自Service,并重写父类的onCreate(),onStartCommand()方法和onDestory() ...

  8. Nginx日志管理配置

    1.创建日志目录 nginx 的默认日志目录所在硬盘空间可能比较小,所以根据硬盘的空间状况创建日志目录 例如:mkdir /backup/nginx_logs 2.修改nginx配置文件 配置 ngi ...

  9. 如何在CentOS7上改变网络接口名

    如何在CentOS7上改变网络接口名 传统上,Linux的网络接口被枚举为eth[0123...],但这些名称并不一定符合实际的硬件插槽,PCI位置,USB接口数量等,这引入了一个不可预知的命名问题( ...

  10. [洛谷P3805]【模板】manacher算法

    题目大意:给你一个字符串,求出它的最长回文字段 题解:$manacher$算法 卡点:$p$数组未开两倍空间 C++ Code: #include <cstdio> #include &l ...