hihoCoder - 1181 - 欧拉路·二 (Fleury算法求欧拉路径)

#1181 : 欧拉路·二

时间限制:10000ms

单点时限:1000ms

内存限制:256MB

描述

在上一回中小Hi和小Ho控制着主角收集了分散在各个木桥上的道具,这些道具其实是一块一块骨牌。

主角继续往前走,面前出现了一座石桥,石桥的尽头有一道火焰墙,似乎无法通过。

小Hi注意到在桥头有一张小纸片,于是控制主角捡起了这张纸片,只见上面写着:

将M块骨牌首尾相连放置于石桥的凹糟中,即可关闭火焰墙。切记骨牌需要数字相同才能连接。
——By 无名的冒险者

小Hi和小Ho打开了主角的道具栏,发现主角恰好拥有M快骨牌。

小Ho:也就是说要把所有骨牌都放在凹槽中才能关闭火焰墙,数字相同是什么意思?

小Hi:你看,每一块骨牌两端各有一个数字,大概是只有当数字相同时才可以相连放置,比如:

小Ho:原来如此,那么我们先看看能不能把所有的骨牌连接起来吧。

提示:Fleury算法求欧拉路径

输入

第1行:2个正整数,N,M。分别表示骨牌上出现的最大数字和骨牌数量。1≤N≤1,000,1≤M≤5,000

第2..M+1行:每行2个整数,u,v。第i+1行表示第i块骨牌两端的数字(u,v),1≤u,v≤N

输出

第1行:m+1个数字,表示骨牌首尾相连后的数字

比如骨牌连接的状态为(1,5)(5,3)(3,2)(2,4)(4,3),则输出"1 5 3 2 4 3"

你可以输出任意一组合法的解。

样例输入
5 5
3 5
3 2
4 2
3 4
5 1
样例输出
1 5 3 4 2 3

Fleury算法伪代码:

DFS(u):
	While (u存在未被删除的边e(u,v))
		删除边e(u,v)
		DFS(v)
	End
	PathSize ← PathSize + 1
	Path[ PathSize ] ← u

这里要注意怎么删边,可以利用vector的erase,也可以利用一个标记来判断是否该边已经删除,比如把要删的边赋值为-1。

vector的删除操作:

#include <vector>
#include <iostream>
using namespace std;

int main(int argc, char** argv)
{
    std::vector<int> vec;
    for(int i=0;i<100;i++)
    {
         vec.push_back(i);
    }

    printf("10:%d\n",vec[10]);
    printf("size:%d\n",vec.size());
    printf("**********************************\n");
    std::vector<int>::iterator it = vec.begin()+10;
    vec.erase(it);

    printf("10:%d\n",vec[10]);
    printf("size:%d\n",vec.size());
    return 0;
}

//输出
//10:10
//size:100
//**********************************
//10:11
//size:99

AC代码(erase):

#include <map>
#include <set>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <cstdio>
#include <cctype>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define INF 0x7fffffff
using namespace std;

int n, m;

const int maxn = 1005;

vector<int> G[maxn];

int path[5005];
int pathsize;

void dfs(int u) {
	int d;
	while((d = G[u].size()) > 0) {
		int v = G[u][0];
//		cout << v << " " << d << endl;
		G[u].erase(G[u].begin());
		int l = G[v].size();
		for(int i = 0; i < l; i ++) {	//找到与u相连的v的与u的连边,因为两边是相互的,要相互删除
			if(G[v][i] == u) {
				G[v].erase(G[v].begin() + i);
				break;
			}
		}
		dfs(v);
	}
	path[pathsize ++] = u;
}

int main() {
	while(scanf("%d %d", &n, &m) != EOF) {
		for(int i = 0; i < m; i ++) {
			int u, v;
			scanf("%d %d", &u, &v);
			G[u].push_back(v);
			G[v].push_back(u);
		}
		pathsize = 0;

		int start = 1;
		while(!G[start].size()) start ++;//找到第一条有连边的点,不过这里数据没有这样的,以后注意而已
		dfs(start);//这里start写1也能AC
		for(int i = 0; i < pathsize - 1; i ++) {
			printf("%d ", path[i]);
		}
		printf("%d\n", path[pathsize - 1]);
	}
	return 0;
}

AC代码(做标记):

#include <map>
#include <set>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <cstdio>
#include <cctype>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define INF 0x7fffffff
using namespace std;

int n, m;

const int maxn = 1005;

vector<int> G[maxn];

int path[5005];
int pathsize;

void dfs(int u) {
	int d = G[u].size();
	for(int i = 0; i < d; i ++) {
		int v = G[u][i];
		if(v != -1) {
			G[u][i] = -1;
			int l = G[v].size();
			for(int j = 0; j < l; j ++) {	//找到与u相连的v的与u的连边,因为两边是相互的,要相互删除
				if(G[v][j] == u) {
					G[v][j] = -1;
					break;
				}
			}
			dfs(v);
		}
	}
	path[pathsize ++] = u;
}

int main() {
	while(scanf("%d %d", &n, &m) != EOF) {
		for(int i = 0; i < m; i ++) {
			int u, v;
			scanf("%d %d", &u, &v);
			G[u].push_back(v);
			G[v].push_back(u);
		}

		int start = 1;
		while(!G[start].size()) start ++;
		pathsize = 0;
		dfs(start);
		for(int i = 0; i < pathsize - 1; i ++) {
			printf("%d ", path[i]);
		}
		printf("%d\n", path[pathsize - 1]);
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-14 19:37:37

hihoCoder - 1181 - 欧拉路·二 (Fleury算法求欧拉路径)的相关文章

hiho欧拉路&#183;二 ----- Fleury算法求欧拉路径

hiho欧拉路·二 分析: 小Ho:这种简单的谜题就交给我吧! 小Hi:真的没问题么? <10分钟过去> 小Ho:啊啊啊啊啊!搞不定啊!!!骨牌数量一多就乱了. 小Hi:哎,我就知道你会遇到问题. 小Ho:小Hi快来帮帮我! 小Hi:好了,好了.让我们一起来解决这个问题. <小Hi思考了一下> 小Hi:原来是这样...小Ho你仔细观察这个例子: 因为相连的两个数字总是相同的,不妨我们只写一次,那么这个例子可以写成:3-2-4-3-5-1.6个数字刚好有5个间隙,每个间隙两边的数字由

HihoCoder1181欧拉路(Fleury算法求欧拉路径)

描述 在上一回中小Hi和小Ho控制着主角收集了分散在各个木桥上的道具,这些道具其实是一块一块骨牌. 主角继续往前走,面前出现了一座石桥,石桥的尽头有一道火焰墙,似乎无法通过. 小Hi注意到在桥头有一张小纸片,于是控制主角捡起了这张纸片,只见上面写着: 将M块骨牌首尾相连放置于石桥的凹糟中,即可关闭火焰墙.切记骨牌需要数字相同才能连接. ——By 无名的冒险者 小Hi和小Ho打开了主角的道具栏,发现主角恰好拥有M快骨牌. 小Ho:也就是说要把所有骨牌都放在凹槽中才能关闭火焰墙,数字相同是什么意思?

hihocoder 1181 欧拉路.二

传送门:欧拉路·二 #1181 : 欧拉路·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回中小Hi和小Ho控制着主角收集了分散在各个木桥上的道具,这些道具其实是一块一块骨牌.主角继续往前走,面前出现了一座石桥,石桥的尽头有一道火焰墙,似乎无法通过.小Hi注意到在桥头有一张小纸片,于是控制主角捡起了这张纸片,只见上面写着: 将M块骨牌首尾相连放置于石桥的凹糟中,即可关闭火焰墙.切记骨牌需要数字相同才能连接. ——By 无名的冒险者 小Hi和小Ho打开了主

hihoCoder #1181: 欧拉路&#183;二 (麻烦)

题意:提供一个图,要求找出欧拉路的路径(任意合法的路径均可,保证图肯定有欧拉路). 思路:深搜的过程中删除遍历过的边,并在回溯时打印出来.在深搜时会形成多个环路,每个环都有一个或多个结点与其他环相扣,这样就可以产生欧拉路. 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=1005; 4 int n, m, a, b; 5 vector< vector<int> > vect;//邻接表 6

HihoCoder1182 欧拉路(Fleury算法)

描述 小Hi和小Ho破解了一道又一道难题,终于来到了最后一关.只要打开眼前的宝箱就可以通关这个游戏了. 宝箱被一种奇怪的机关锁住: 这个机关是一个圆环,一共有2^N个区域,每个区域都可以改变颜色,在黑白两种颜色之间切换. 小Ho控制主角在周围探索了一下,果然又发现了一个纸片: 机关黑色的部分表示为1,白色的部分表示为0,逆时针连续N个区域表示一个二进制数.打开机关的条件是合理调整圆环黑白两种颜色的分布,使得机关能够表示0~2^N-1所有的数字. 我尝试了很多次,终究没有办法打开,只得在此写下机关

Fleury算法求欧拉路径 hiho第50周

题目链接: hiho一下 第五十周 思路:hiho已经讲的非常好了,我就不插嘴了. 提示:因为建边时同一条边同相反相的编号相近,比如(u-v)正向边u->v标号为0,反向边v->u标号为1,而0或1除以2都等于0,所以无论正反向建边,只要访问过正向反向中的任何一条边都可以用head[u]/2把原边标记为vis=1操作 /************************************************************** Problem:hiho 50 User: you

[hihoCoder] 第五十周: 欧拉路&#183;二

题目1 : 欧拉路·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回中小Hi和小Ho控制着主角收集了分散在各个木桥上的道具,这些道具其实是一块一块骨牌. 主角继续往前走,面前出现了一座石桥,石桥的尽头有一道火焰墙,似乎无法通过. 小Hi注意到在桥头有一张小纸片,于是控制主角捡起了这张纸片,只见上面写着: 将M块骨牌首尾相连放置于石桥的凹糟中,即可关闭火焰墙.切记骨牌需要数字相同才能连接. ——By 无名的冒险者 小Hi和小Ho打开了主角的道具栏,发现主角

hihoCoder 第 50 周欧拉路二之C实现方法

题目1 : 欧拉路·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回中小Hi和小Ho控制着主角收集了分散在各个木桥上的道具,这些道具其实是一块一块骨牌. 主角继续往前走,面前出现了一座石桥,石桥的尽头有一道火焰墙,似乎无法通过. 小Hi注意到在桥头有一张小纸片,于是控制主角捡起了这张纸片,只见上面写着: 将M块骨牌首尾相连放置于石桥的凹糟中,即可关闭火焰墙.切记骨牌需要数字相同才能连接. --By 无名的冒险者 小Hi和小Ho打开了主角的道具栏,发现主角

hiho一下 第五十周 题目1 : 欧拉路&#183;二

时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回中小Hi和小Ho控制着主角收集了分散在各个木桥上的道具,这些道具其实是一块一块骨牌. 主角继续往前走,面前出现了一座石桥,石桥的尽头有一道火焰墙,似乎无法通过. 小Hi注意到在桥头有一张小纸片,于是控制主角捡起了这张纸片,只见上面写着: 将M块骨牌首尾相连放置于石桥的凹糟中,即可关闭火焰墙.切记骨牌需要数字相同才能连接. ——By 无名的冒险者 小Hi和小Ho打开了主角的道具栏,发现主角恰好拥有M快骨牌. 小H