欧拉路问题

 首先对于无向图的欧拉路的成立条件是:1、联通   2、每个点度数为偶数或者当且仅当存在两个点读书为奇数

对于有向图:1、每个点度数的出度等于入度(欧拉回路)2、一个点出度比入度大一,另一个点入度比出度大一,其他点入度与出度相等。

至于怎样寻找欧拉路,首先很好确定起点(很好确定),然后直接dfs,但是要注意的是一定要用后序遍历,因为只有后序遍历对于入度比出度大的点才能被作为终点。

下面是模板:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
vector<int >g[10005];
int vis[100005];
int in[10005],out[10005],use[10005];
char c[6];
int a[200005],cnt;
int change(char c){
    if(c>='a'&&c<='z') return c-'a';
    if(c>='A'&&c<='Z') return 26+c-'A';
    return 52+c-'0';
}
void add(int a,int b){
    g[a].push_back(b);
}
int it[10005];
void dfs(int u,int ee){
    int p;
    p=(int)g[u].size();
    while(it[u]<p){
        int m=it[u];
        it[u]++;
        use[g[u][m]]=1;
        dfs(g[u][m],0);
    }
    a[cnt++]=u;//放外面的好处是对于不能走的点也可以记录,而且一定要后序(因为后序能保证不能走的点一定是终点,而先序却不行)
}
int main()
{
    int i,m;
    int x=0,y=0;
    m=0;
    for(i=0;i<=10000;i++){
        if(in[i]!=out[i]){
            if(in[i]==out[i]+1){
                x++;
            }
            else if(out[i]==in[i]+1){
                y++;
            }
            else{
                m=1;
            }
        }
    }
    if(!((x==0&&y==0)||(x==1&&y==1))) m=1;//
    if(m) printf("NO\n");
    else{
        if(x==0){
            for(i=0;i<=10000;i++){
                if(in[i]!=0){
                    use[i]=1;
                    dfs(i,0);
                    break;
                }
            }
        }
        else{
            for(i=0;i<=10000;i++){
                if(out[i]==in[i]+1){
                    use[i]=1;
                    dfs(i,0);
                    break;
                }
            }
        }
        for(i=0;i<=10000;i++){
            if(!(in[i]==0&&out[i]==0)){
                if(!use[i]){
                    m=1;
                    break;
                }
            }
        }
        if(m) printf("NO\n");
        else{
            printf("YES\n");
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值