Hierholzer算法dfs找欧拉回路模板

简介: Hierholzer算法dfs找欧拉回路模板

dfs找欧拉回路


#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10,M=2e5+10;
int h[N],e[M*2],ne[M*2],idx;
int n,m;
int t;
int dout[N];
int din[N];
bool vis[M*2];
int p[M*2];
int cnt=0;
void add(int a,int b)
{
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u)
{
    for(int &i=h[u];i;i=ne[i])
    {
        if(vis[i]) continue;
        vis[i]=true;  
        if(t==1) vis[i^1]=true;
        int no;
         if(t==1)
        {
            if((i&1))
            {
              no=-(i/2);
            }else no=i/2;
        }else
        {
            no=i-1;
        }
       int j=e[i];
        dfs(j);
       p[++cnt]=no;
    }
}
int main()
{
    scanf("%d",&t);
    scanf("%d%d",&n,&m);
    idx=2;
    for(int i=1;i<=m;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        add(a,b);
        dout[a]++;
        din[b]++;
        if(t==1) add(b,a);
    }
    if(t==1)
    {
        for(int i=1;i<=n;i++)
        {
            if((din[i]+dout[i])%2!=0)
            {
                cout<<"NO"<<endl;
                return 0;
            }
        }
    }else
    {
        for(int i=1;i<=n;i++)
        {
            if(din[i]!=dout[i])
            {
                cout<<"NO"<<endl;
                return 0;
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
        if(h[i])
        {
            dfs(i);
            break;
        }
    }
    if(cnt!=m)
    {
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i=cnt;i>=1;i--)
    {
        cout<<p[i]<<' ';
    }
    cout<<endl;
}

求逆字典序最小的欧拉路径

#include<bits/stdc++.h>
using namespace std;
const int N=510,M=2000;
int g[N][N];
int m;
int d[N];
int ans[M];
int cnt;
void dfs(int u)
{
    for(int i=1;i<=500;i++)
    {
        if(g[u][i])
        {
            g[u][i]--,g[i][u]--;
            dfs(i);
        }
    }    ans[++cnt]=u;
}
int main()
{
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        g[a][b]++;
        g[b][a]++;
        d[a]++;
        d[b]++;
    }
    int start=1;
    for(int i=1;i<=500;i++)
    {
        if(d[i]%2)
        {
        start=i;
            break;
        }
    }
    dfs(start);
    for(int i=cnt;i;i--)
    {
        printf("%d\n",ans[i]);
    }
}

求字典序最小的以点表示的欧拉路径

#include <bits/stdc++.h>
using namespace std;
#define x first
#define y second
# define rep(i,be,en) for(int i=be;i<=en;i++)
# define pre(i,be,en) for(int i=be;i>=en;i--)
#define ll long long
#define endl "\n"
#define LOCAL
#define pb push_back
typedef pair<ll, ll> PII;
#define eb emplace_back
#define sp(i) setprecision(i)
const int N = 1e5 + 10, INF = 0x3f3f3f3f;
int din[N];
int dout[N];
vector<int>g[N];
int n,m;
int ans[N*2];
int del[N];
int cnt=0;
stack<int>s;
void dfs(int u)
{
    for(int i=del[u];i<g[u].size();i=del[u])
    {
        del[u]=i+1;
        dfs(g[u][i]);
    }
    //s.push(u);
     ans[++cnt]=u;
}
void solve()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        g[a].push_back(b);
        din[b]++;
        dout[a]++;
    }
    for(int i=1;i<=n;i++) sort(g[i].begin(),g[i].end());
    int start=1;
    int f1=0;
    int f2=0;
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        if(dout[i]!=din[i])
        {
            sum++;
            if(dout[i]==din[i]+1)
            {
                f2++;
            }else if(dout[i]+1==din[i])
            {
                f1++;
            }
        }
    }
    if(!(sum==0||(sum==2&&f1==1&&f2==1)))
    {
        printf("No\n");
        return;
    }
    for(int i=1;i<=n;i++)
    {
        if(din[i]+1==dout[i])
        {
            start=i;
            break;
        }
    }  
    dfs(start);
    for(int i=cnt;i>=1;i--)
    {
        printf("%d ",ans[i]);
    }
    // while(s.size()) 
    // {
    //     cout<<s.top()<<' ';
    //     s.pop();
    // }
    puts("");
}
signed main() {
// std::ios::sync_with_stdio(false);
//     std::cin.tie(nullptr);
    //#ifdef LOCAL
    //freopen("data.in.txt","r",stdin);
    //freopen("data.out.txt","w",stdout);
    //#endif
    int __ = 1;
    //cin>>__;
    while (__--)
        {
            solve();
        }
    return 0;
}


目录
相关文章
|
2月前
|
算法 测试技术 定位技术
数据结构与算法——DFS(深度优先搜索)
数据结构与算法——DFS(深度优先搜索)
|
4月前
|
算法
DFS算法的实现
DFS算法的实现
68 3
|
4月前
|
算法
【算法】前缀和——二维前缀和模板题
【算法】前缀和——二维前缀和模板题
|
6月前
|
存储 算法 Java
Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。
【6月更文挑战第21天】Java中,树与图的算法涉及二叉树的前序、中序、后序遍历以及DFS和BFS搜索。二叉树遍历通过访问根、左、右子节点实现。DFS采用递归遍历图的节点,而BFS利用队列按层次访问。以下是简化的代码片段:[Java代码略]
50 4
|
29天前
|
算法 vr&ar 计算机视觉
数据结构之洪水填充算法(DFS)
洪水填充算法是一种基于深度优先搜索(DFS)的图像处理技术,主要用于区域填充和图像分割。通过递归或栈的方式探索图像中的连通区域并进行颜色替换。本文介绍了算法的基本原理、数据结构设计(如链表和栈)、核心代码实现及应用实例,展示了算法在图像编辑等领域的高效性和灵活性。同时,文中也讨论了算法的优缺点,如实现简单但可能存在堆栈溢出的风险等。
41 0
|
6月前
|
算法 Java 数据处理
Java算法模板 数据流快读
Java算法模板 数据流快读
51 2
|
6月前
|
算法
数据结构与算法-DFS+BFS篇(迷宫问题)
数据结构与算法-DFS+BFS篇(迷宫问题)
89 3
|
5月前
|
设计模式 JavaScript 算法
vue2 原理【详解】MVVM、响应式、模板编译、虚拟节点 vDom、diff 算法
vue2 原理【详解】MVVM、响应式、模板编译、虚拟节点 vDom、diff 算法
195 0
|
6月前
|
算法 Java
Java数据结构与算法:图算法之深度优先搜索(DFS)
Java数据结构与算法:图算法之深度优先搜索(DFS)
下一篇
DataWorks