欧拉路径&&欧拉回路
定义:
欧拉路径:指图中的一条路径,使得所有边都被经过且只经过一次
欧拉回路:指图中的一条欧拉路径,且起点和终点相同。
欧拉图:指有欧拉回路的图
半欧拉图:指有欧拉路径但没有欧拉回路的图
性质:
1.如果一个无向图是欧拉图,那么所有节点的度数均为偶数
2.如果一个无向图是半欧拉图,那么除了两个节点的度数为奇数,其他的节点度数都为偶数
3.如果一个有向图是欧拉图,那么对于每个节点,它的入度和出度相等。
4.如果一个有向图是半欧拉图,那么除了两个节点的入出度差为
HierHolzer:
problem:
给定图
solution:
先考虑生成欧拉路径:
1.找到出度减入度为
2.考虑
3.标记
4.对
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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步