欧拉回路
定理:一个非平凡连通图G是Euler图当且仅当图G没有奇点。
 欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路? 

Input

测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是节点数N ( 1 < N < 1000 )和边数M;随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号(节点从1到N编号)。当N为0时输入结
束。

Output

每个测试用例的输出占一行,若欧拉回路存在则输出1,否则输出0。

Sample Input

3 3
1 2
1 3
2 3
3 2
1 2
2 3
0

Sample Output

1
0

1.用并查集

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1e3+5;
int v[maxn];
int degree[maxn];
int n,m;
void init()
{
    for(int i=1;i<=n;++i)
    {
        v[i]=i;
    }
    return ;
}
int find(int x)
{
    if(x==v[x])
    {
        return x; 
    }
    return v[x]=find(v[x]);
}
void merge(int x,int y)
{
    v[find(x)]=find(y);
}
int main()
{
    int x,y;
    while(cin>>n)
    {
        if(n==0)
        {
            break;    
        }    
        cin>>m;
        memset(degree,0,sizeof(degree));
        init();
        for(int i=1;i<=m;++i)
        {
            cin>>x>>y;
            merge(x,y);
            degree[x]++;
            degree[y]++;
        }
        for(int i=1;i<=n;++i)
        {
            find(i);
        }
        bool ans = true;
        int father = v[1];
        for(int i=1;i<=n;++i)
        {
            if(v[i]!=father)
            {
                ans = false;
                break;
            }
            if(degree[i]%2==1)
            {
                ans = false;
                break;
            }
        }
        printf("%d\n",ans==true?1:0);
    }
    return 0;
}

2.dfs

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1e3+5;
int map[maxn][maxn];
int degree[maxn];
int vis[maxn];
int dfs(int x,int n)
{
    vis[x]=1;
    for(int i=1;i<=n;++i)
    {
        if(!vis[i] && map[x][i])                //如果该点没有被搜索过同时该点和i之间有边 
        {
            dfs(i,n);
        }
    }
    return 0;
}
int main()
{
    int n,m;
    while(cin>>n>>m)    //n个结点m个边 
    {
        memset(map,0,sizeof(map));
        memset(degree,0,sizeof(degree)); 
        memset(vis,0,sizeof(vis));
        int x,y;
        for(int i=0;i<m;++i)
        {
            cin>>x>>y;
            map[x][y]=1;
            map[y][x]=1;
            degree[x]++;
            degree[y]++;
        }
        dfs(1,n);
        bool ans = true; 
        for(int i=1;i<=n;++i)            //判断每个点 
        {
            if(!vis[i])                    //多个连通分治 
            {
                ans = false;
                break;
            }
            if(degree[i]%2==1)
            {
                ans = false;
                break;
            }
        }
        printf("%d\n",ans==true?1:0);
    }
    return 0;
}
Last modification:December 21st, 2019 at 11:08 pm
如果觉得我的文章对你有用,请随意赞赏