您的位置:首页 > 其它

Poj 2230 Watchcow (欧拉回路)打印欧拉回路路径

2017-11-08 17:00 323 查看
点击打开题目链接

我之前在博客中写过如何判断一个图如何为欧拉回路,但是写的太过简略,在此再次说明一下欧拉回路是什么,顺写一下如何打印路径。

欧拉回路:欧拉回路就是从图上的一点出发,经过所有的边必须且只能一次,最终回到起点的路径。

如何判断一个图为欧拉回路:

1.对于任意一个图来说,必须这个图是连通的,不能有孤立的点。

2,在此分两种类型的图来说

 <1> 无向图:对于无向图来说度数为奇数的点的个数为0;

 <2>有向图:每个定点的入度等于出度。

判断连通我之前博客中有用DFS来判断,思路非常简单,用一个标记数组来标记点是否用过,然后dfs任意一点,然后把搜索到的标记,然后最后判断是否有点没有搜索到。

然后条件2只需要统计图中每个点的入度和出度即可判断。

以上是最基本的欧拉回路的条件。

欧拉回路有一种变形,就是不回到原点,,但是依旧要所有的边必须且只能一次,也就是所谓的一笔画问题。

对于这种问题,是否为一笔画的判断条件如下:

1.图必须连通,不存在孤立点。

2,在此分两种类型的图来说

 <1> 无向图:对于无向图来说度数为奇数的点的个数为2,一个为终点,一个为起点;

 <2>有向图:存在两个点,其入度不等于出度,其中一点出度比入度大1为路径的起点,另一个入度比出度大一为路径的终点。

以上是判断一个图是否为欧拉图。但是很多情况只知道如何判断是无法解决问题的,最重要的还是求出路径。

在此提供两种思路:

第一种特别简单,暴搜,按照边来搜索整张图,直到搜索出一跳路径包含所有边为止。但是时间复杂度太高=-=,慎用!!!

第二种是带有一定的技巧性,实际上就是标记边,考虑搜索的的过程,当我们搜索到一个回路时,无非是两种情况,是答案,或者不是答案。因为确定我们这个图是在欧拉回路上搜索的,那么一定存在,一个路径是答案。于此同时我们还要标记每一个我们找到的边。表示我们已经用过这条边。那么我们怎么简化这个过程呢,假设没有搜索到答案,我们搜索开始回溯时,找到了第一个可以向其他方向搜索的时候,我们一定可以,在这个方向上找到一条路径来形成一个到达原点的道路,这时候一定面临两种情况是答案或者不是答案。如果不是继续回溯,重复上述过程,知道搜索结束。

总结下来就是,每次搜索到某条边时,把这条边记录成已选择,并且回溯也不能将当前边的状态改变回来。,每次回溯时记录回溯的路径。

说了这么多来看一下这道题的题意:

一个人要在n个节点上走,最后必须走到。原点,并且每个两个节点之间必须走两次。让你找出这样的一条路径。

思路:欧拉回路解决

代码如下:

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

const int N = 1e5 + 5;
const int M = 1e5 + 5;

struct EdgeNode{
int to;
int w;
int next ;
};
EdgeNode Edges[M];
int head
;
int n,m;

int ans[M];
int ansi = 0;
bool visit[2*M];
void DFS(int now){
int k ;
for(int k = head[now] ; k != -1 ; k = Edges[k].next){
if(!visit[k]){
visit[k] = true;
//visit[k^1] = true;
DFS(Edges[k].to);
ans[ansi++] = Edges[k].to;
}
}
}
int main(){

cin >> n >> m;
memset(head,-1,sizeof(head));
for(int i = 1; i <= 2*m ;i += 2){
int a,b;
cin >> a >> b;
Edges[i].to = b;
Edges[i].next = head[a];
head[a] = i;
Edges[i^1].to = a;
Edges[i^1].next = head[b];
head[b] = i ^ 1;
}
// for(int i = 1 ; i <= n ; i ++){
// for(int k = head[i] ; k != -1 ; k = Edges[k].next)
// cout << i << " " << Edges[k].to << endl;
// }
DFS(1);
for(int i = 0 ; i < ansi ; i++)
cout << ans[i] << endl;
cout << "1" << endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: