SGU 156. Strange Graph(欧拉路)
时间限制:0.25s
空间限制:6M
题目描述
让我们想象一个无向图G=<V,E>.如果边(u,v)在边集E中,那么我们就说两个顶点u和v是邻接点.在这种情况下,我们也说u是v的一个邻接点且v是u的一个邻接点.我们用N(v)表示点v的邻接点集
合.我们知道v的邻接点数目也叫作这个点的度,用deg v表示.
我们说图G是奇怪的如果它是连通的且对于它的每一个点满足如下条件:
1. 点v的度deg v>=2(表明v的邻接点至少有两个)
2. 如果点v的度deg v=2,那么它的两个邻接点之间没有边相连
3. 如果点v的度deg v>2,那么在它的邻接点集合N(v)中存在点u满足:
(a)点u的度deg u=2
(b)集合N(v)中除顶点u外任意两个不同的点是相邻的,即(w1,w2)这条边存在于边集E中.
现在给你某个这样的图,在里面找出一条哈密尔顿回路,一条哈密尔顿回路就是一条回路,这条回路经过图G中的每一点,且只经过一次.
输入
输入文件的第一行包含两个整数N和M——N为图G中定点的数目,M为图G中边的数目
(3<=N<=10000,M<=100000).接下来为2M个整数(每相邻两个点为一对)——每对数代表一条边的两个顶点(顶点被编号为1-N).输入数据保证每条边仅出现一次,且没有这样的环(边的两端点相同).
输出
如果在图G中没有哈密尔顿回路,则在输出文件的第一行输出-1.如果存在,则输出N个数——即在图G中找到的哈密尔顿回路的顶点序列(注意:最后一个点必须与第一个点相连).
如果有多种解,则输出任意一种即可.
Sample input #1
4 4
1 2 2 3 3 4 4 1
Sample input #2
9 12
1 2 2 3 3 1 1 4 2 5 3 6
4 7 5 8 6 9 7 8 8 9 9 7
Sample output #1
1 2 3 4
Sample output #2
-1
分析:
给出一个联通的图,保证每个点的度至少为2.
并且对于度大于2的点,相连的有一个度为2的点,其它相连的点之间都有边。
对于这个图求它的哈密顿回路。
先来分析这个奇怪的图,从样例2也可以看出对于这样的图是无法保证有解的。
从这里似乎需要判断哈密顿回路的存在与否,但是判断哈密顿回路的存在问题是NP的。
这就使得我们转换思路。
回忆起SGU的SGU 101.Domino(多米诺骨牌),在这一题,我们放弃寻找一个哈密顿路,重新建图变成了一个求欧拉路的问题。
这里是不是也可以呢?
考虑一个点u,假设它与a,b,v相连,
v是一个度为2的点,那么a,b之间一定有边,并且它们还有一条边连向一个度为2的节点
显然边G(u,a,b)是一个完全图,而且能够以任意方式互相遍历
这时我们可以将V(u,a,b)看成一个点。
接下来的问题就是求新得到的图的欧拉回路了。
每次进入完全子图时,走不同的边。
时间复杂度O(n+m);
code(46ms AC)
/*
前向星存边,对于一个完全子图用并查集进行合并,存入f[].
寻找欧拉路时每次只在一个完全子图中用一条边,并标记走过的点,直接输出答案.
*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int INF = int (1e4 + 9);
//前向星存边
struct Edge {
int u, v, ne;
} edge[INF * 20];
int head[INF], deg[INF], vise[INF * 20], vis[INF], f[INF], cnt = 1;
int n, m, x, y; void addedge (int u, int v) {
edge[++cnt].u = u, edge[cnt].v = v;
edge[cnt].ne = head[u], head[u] = cnt;
}
//合并完全子图
void change() {
for (int i = 1; i <= n; i++)
if (deg[i] > 2 && !vis[i]) {
for (int j = head[i]; j != 0; j = edge[j].ne) {
int v = edge[j].v;
if (deg[v] > 2)
f[v] = i, vis[v] = 1;
}
}
}
void EulerianPath (int x, int p) {
vis[x] = 1;
for (int i = head[x]; i != 0; i = edge[i].ne) {
if (vise[i] || vis[edge[i].v]) continue;
int u = edge[i].u, v = edge[i].v;
if (p && f[u] == f[v]) {
vise[i] = vise[i ^ 1] = 1;
//由内传来
EulerianPath (v, 0);
}
if (deg[x] == 2 || (!p && f[u] != f[v]) ) {
vise[i] = vise[i ^ 1] = 1;
//由外传来
EulerianPath (v, 1);
}
}
printf ("%d ", x);
}
//判断并寻找欧拉回路
void Eulerian() {
int t = 0;
for (int i = 1; i <= n; i++) {
if (!f[i] && deg[i] & 1) {
t++; break;
}
if (!f[i]) f[i] = i;
}
if (t != 0) {
puts ("-1"); return;
}
memset (vis, 0, sizeof vis);
EulerianPath (1, 0);//如果存在哈密顿回路以任意起点出发均可
}
int main() {
scanf ("%d %d", &n, &m);
for (int i = 1; i <= m; i++) {
scanf ("%d %d", &x, &y);
addedge (x, y), addedge (y, x);
deg[x]++, deg[y]++;
}
change();
Eulerian();
return 0;
}
SGU 156. Strange Graph(欧拉路)的更多相关文章
- SGU 156 Strange Graph 欧拉回路,思路,汉密尔顿回路 难度:3
http://acm.sgu.ru/problem.php?contest=0&problem=156 这道题有两种点 1. 度数>2 在团中的点,一定连接一个度数为2的点 2. 度数等 ...
- SGU 101.Domino (欧拉路)
时间限制: 0.5 sec 空间限制: 4096 KB 描述 多米诺骨牌,一种用小的方的木块或其他材料,每个都被一些点在面上标记,这些木块通常被称为骨牌.每个骨牌的面都被一条线分成两个 方形,两边 ...
- hiho48 : 欧拉路·一
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho最近在玩一个解密类的游戏,他们需要控制角色在一片原始丛林里面探险,收集道具,并找到最后的宝藏.现在他们控制的 ...
- [hihoCoder] 第五十周: 欧拉路·二
题目1 : 欧拉路·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回中小Hi和小Ho控制着主角收集了分散在各个木桥上的道具,这些道具其实是一块一块骨牌. 主角 ...
- 洛谷P1341 无序字母对[无向图欧拉路]
题目描述 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现. 输入输出格式 输入格式: 第一行输入一 ...
- POJ1386Play on Words[有向图欧拉路]
Play on Words Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 11846 Accepted: 4050 De ...
- hdu1161 欧拉路
欧拉路径是指能从一个点出发能够“一笔画”完整张图的路径:(每条边只经过一次而不是点) 在无向图中:如果每个点的度都为偶数 那么这个图是欧拉回路:如果最多有2个奇数点,那么出发点和到达点必定为该2点,那 ...
- UVA10054The Necklace (打印欧拉路)
题目链接 题意:一种由彩色珠子组成的项链.每个珠子的两半由不同的颜色组成.相邻的两个珠子在接触的地方颜色相同.现在有一些零碎的珠子,需要确定他们是否可以复原成完整的项链 分析:之前也没往欧拉路上面想, ...
- 洛谷 P1341 无序字母对 Label:欧拉路 一笔画
题目描述 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现. 输入输出格式 输入格式: 第一行输入一 ...
随机推荐
- (转载)linux中shell变量
(转载)http://blog.csdn.net/zahuopuboss/article/details/8633891 为使shell编程更有效,系统提供了一些shell变量.shell变量可以保存 ...
- 数据结构(莫队算法):国家集训队2010 小Z的袜子
[题目描述] 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命…… 具体来说,小Z把这N只袜子从1到 ...
- Delphi中使用TXMLDocument控件应注意的问题 转
Delphi中使用TXMLDocument控件应注意的问题 delphiconstructorxmlclass今天写了一个类,其中用到了TXMLDocument控件.这个控件我是要动态生成的. 但是却 ...
- 解决外部机器通过VM内ubuntu IP 无法访问vm内web服务的问题
1. 2.i root@ubuntu:/home/udapeng# ifconfig root@ubuntu:/www/sentry# nano uwsgi.ini root@ubuntu:/www/ ...
- Android四大组件之ContentProvider(二)读取设备上的图片、音频和视频
Android系统提供了MediaScanner,MediaProvider,MediaStore等接口,通过Content Provider的方式提供给用户.当设备开机或者有SD卡插拔等事件发生时, ...
- Graphs and Minimum Cuts(Karger's Min-Cut Algorithm)
Graphs Two ingredients 1. vertices (nodes) v 2. edges(undirected or directed) Examples: road networ ...
- Parallel.Foreach的并发问题解决方法-比如爬虫WebClient
场景五:线程局部变量 Parallel.ForEach 提供了一个线程局部变量的重载,定义如下: public static ParallelLoopResult ForEach<TSource ...
- python 开发简单的聊天工具
python 太强大了,以至于它什么都可以做,哈哈,开个玩笑.但是今天要讲的真的是一个非常神奇的应用. 使用python写一个聊天工具 其实大家平时用的QQ类似的聊天工具,也是使用socket进行聊天 ...
- win7重装系统时,使用PE工具箱进入系统看到的“C盘变成0.2G,D盘变成48G左右”这是什么回事?
引入: 今天帮同学重装系统,重装系统使用的方法是利用PE工具箱制作出启动U盘,进行重装系统. 我的步骤是 第一步:开机按F2挂载U盘优先启动,于是开机时就进入PE微系统 第二步: 用分区工具(Disk ...
- PHP运行出现Notice : Use of undefined constant 的完美解决方案
Notice: Use of undefined constant title - assumed 'title' in F:\wamp\www\load_myweb.php on line 22No ...