Hierholzer算法dfs找欧拉回路模板

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是用R语言实现hierholzer算法欧拉通路的代码: ```R # 定义一个函数,用于实现hierholzer算法 find_eulerian_path <- function(adj_list) { # 初始化一个栈,用于存储路径 stack <- list() # 初始化一个空的欧拉路径 euler_path <- list() # 随机选择一个起点 start_node <- sample(names(adj_list), 1) # 将起点入栈 stack[[1]] <- start_node while (length(stack) > 0) { # 取出栈顶元素 curr_node <- stack[[length(stack)]] # 如果当前节点没有邻居节点,则将当前节点出栈,并将其加入欧拉路径 if (length(adj_list[[curr_node]]) == 0) { stack <- stack[-length(stack)] euler_path <- c(euler_path, curr_node) } else { # 否则,随机选择一个邻居节点,并从邻居节点列表中删除该节点 next_node <- sample(adj_list[[curr_node]], 1) adj_list[[curr_node]] <- adj_list[[curr_node]][-which(adj_list[[curr_node]] == next_node)] # 将邻居节点入栈 stack[[length(stack) + 1]] <- next_node } } # 将欧拉路径反转,并返回结果 return(rev(euler_path)) } # 测试代码 # 定义一个邻接表,用于表示有向图 adj_list <- list( "A" = c("B", "C"), "B" = c("C", "D"), "C" = c("E"), "D" = c("A"), "E" = c("B") ) # 查欧拉通路 path <- find_eulerian_path(adj_list) # 输出结果 cat("欧拉通路:", paste(path, collapse = " -> "), "\n") ``` 该代码实现了hierholzer算法,用于查有向图的欧拉通路。其中,`adj_list`表示有向图的邻接表,`find_eulerian_path`函数用于查欧拉通路。在函数中,我们先随机选择一个起点,然后使用栈来实现欧拉路径的查。具体实现过程见代码注释。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值