快来踩爆这个蒟蒻吧|

Little_corn

园龄:1年1个月粉丝:10关注:17

2024-04-25 13:04阅读: 12评论: 0推荐: 0

欧拉路径&&欧拉回路

定义:

欧拉路径:指图中的一条路径,使得所有边都被经过且只经过一次

欧拉回路:指图中的一条欧拉路径,且起点和终点相同。

欧拉图:指有欧拉回路的图

半欧拉图:指有欧拉路径但没有欧拉回路的图

性质:

1.如果一个无向图是欧拉图,那么所有节点的度数均为偶数

2.如果一个无向图是半欧拉图,那么除了两个节点的度数为奇数,其他的节点度数都为偶数

3.如果一个有向图是欧拉图,那么对于每个节点,它的入度和出度相等。

4.如果一个有向图是半欧拉图,那么除了两个节点的入出度差为 1 以外,其他节点入出度差都为 0(即相等)。

HierHolzer:

problem:

给定图 G,求 G 中字典序最小的欧拉路径

solution:

先考虑生成欧拉路径:

1.找到出度减入度为 1 的节点(假如没有默认为 1 号节点),将其作为起始节点进行 dfs

2.考虑 u 节点未访问过的边 (u,v),如果没有,将 u 节点压入栈并返回。

3.标记 (u,v) 为已访问。

4.对 v 进行2,3操作。

5.所有操作完成后,将栈中元素输出。

通过这里我们知道,元素是倒序输出的,所以我们要让后面的元素尽量小,所以其实就是要将链式前向星中的元素从大到小排序。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
struct edge{
int v,next;
}edges[N*2];
int head[N],idx;
int n,m;
void add_edge(int u,int v){
idx++;
edges[idx].v=v;
edges[idx].next=head[u];
head[u]=idx;
return;
}
int stk[N*3],top;
void dfs(int u){
for(int i=head[u];i;i=head[u]){
int v=edges[i].v;
head[u]=edges[i].next;
dfs(v);
}
stk[++top]=u;
return;
}
int degin[N],degout[N];
struct stu{
int u,v;
}st[N*2];
bool cmp(struct stu st1,struct stu st2){
if(st1.u==st2.u)return st1.v>st2.v;
return st1.u>st2.u;
}
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>st[i].u>>st[i].v;
}
sort(st+1,st+m+1,cmp);
for(int i=1;i<=m;i++){
add_edge(st[i].u,st[i].v);
degin[st[i].v]++;
degout[st[i].u]++;
}
int s=1,cnt=0;
for(int i=1;i<=n;i++){
if(abs(degin[i]-degout[i])&1)cnt++;
if(degout[i]-degin[i]==1)s=i;
}
if(cnt!=2&&cnt!=0){
cout<<"No"<<endl;
return 0;
}
dfs(s);
while(top>0){
cout<<stk[top]<<" ";
top--;
}
return 0;
}

本文作者:Little_corn

本文链接:https://www.cnblogs.com/little-corn/p/18157440

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Little_corn  阅读(12)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起