UVA 10054 The Necklace (无向图的欧拉回路)
本文链接: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 (无向图的欧拉回路)的更多相关文章
- UVa 10054 The Necklace(无向图欧拉回路)
My little sister had a beautiful necklace made of colorful beads. Two successive beads in the neckla ...
- uva 10054 The Necklace 拼项链 欧拉回路基础应用
昨天做了道水题,今天这题是比较水的应用. 给出n个项链的珠子,珠子的两端有两种颜色,项链上相邻的珠子要颜色匹配,判断能不能拼凑成一天项链. 是挺水的,但是一开始我把整个项链看成一个点,然后用dfs去找 ...
- UVa 10054 The Necklace BFS+建模欧拉回路
算法指南 主要就是建立欧拉回路 #include <stdio.h> #include <string.h> #include <iostream> #includ ...
- UVA 10054 The Necklace 转化成欧拉回路
题意比较简单,给你n个项链碎片,每个碎片的两半各有一种颜色,最后要把这n个碎片串成一个项链,要求就是相邻碎片必须是同种颜色挨着. 看了下碎片总共有1000个,颜色有50种,瞬间觉得普通方法是无法在可控 ...
- UVA 10054 The Necklace(欧拉回路,打印路径)
题目链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- uva 10054 The Necklace(欧拉回路)
The Necklace My little sister had a beautiful necklace made of colorful beads. Two successive beads ...
- UVA 10054 the necklace 欧拉回路
有n个珠子,每颗珠子有左右两边两种颜色,颜色有1~50种,问你能不能把这些珠子按照相接的地方颜色相同串成一个环. 可以认为有50个点,用n条边它们相连,问你能不能找出包含所有边的欧拉回路 首先判断是否 ...
- UVa 10054 The Necklace【欧拉回路】
题意:给出n个珠子,珠子颜色分为两半,分别用1到50之间的数字表示, 现在给出n个珠子分别的颜色,问是否能够串成一个环.即为首尾相连,成为一个回路 判断是否构成一个环,即判断是否为欧拉回路,只需要判断 ...
- 【欧拉回路】UVA - 10054 The Necklace
题目大意: 一个环被切割成了n个小块,每个小块有头尾两个关键字,表示颜色. 目标是判断给出的n个小块能否重构成环,能则输出一种可行解(按重构次序输出n个色块的头尾颜色).反之输出“some beads ...
随机推荐
- how to export chrome speed dial extension?
locate chrome-extension_dgpdioedihjhncjafcpgbbjdpbbkikmi_0.localstorage, copy it to you want, everyt ...
- 《Cracking the Coding Interview》——第18章:难题——题目6
2014-04-29 02:27 题目:找出10亿个数中最小的100万个数,假设内存可以装得下. 解法1:内存可以装得下?可以用快速选择算法得到无序的结果.时间复杂度总体是O(n)级别,但是常系数不小 ...
- USACO Section2.2 Subset Sums 解题报告 【icedream61】
subset解题报告------------------------------------------------------------------------------------------ ...
- 每天一个Linux命令(10):mv命令
mv命令用来对文件或目录重新命名,或者将文件从一个目录移到另一个目录中.source表示源文件或目录,target表示目标文件或目录.如果将一个文件移到一个已经存在的目标文件中,则目标文件的内容将被覆 ...
- Python 3基础教程8--if else、if elif else
本文介绍if else语句,不多说,直接看例子. if elif else语句
- springboot整合jersey
https://blog.csdn.net/xiongpei00/article/details/76576420
- 一个初学者的辛酸路程-基于Django写BBS项目
前言 基于Django的学习 详情 登录界面 找个模板 http://v3.bootcss.com/examples/signin/ 右键,检查源码 函数 def login(request) ...
- 孤荷凌寒自学python第三十一天python的datetime.timedelta模块
孤荷凌寒自学python第三十一天python的datetime.timedelta模块 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) datetime.timedelta模块是一个表示 ...
- [Leetcode/Javascript] 461.Hamming Distance
[Leetcode/Javascript] 461.Hamming Distance 题目 The Hamming distance between two integers is the numbe ...
- 真的讨厌ClickOnce这东西
ClickOnce真的问题多. 升级问题,每次升级后都新建一个文件夹,旧的程序数据全都没有.迁移过来也一堆问题.还有录音问题,Win7下录音报错,最后查来查去就是将文件路径太太长,要控制长度.还有安装 ...