欧拉回路

资料:http://blog.csdn.net/tiantangrenjian/article/details/6793869

经典七桥问题:


对无向图:  

定义:给定无孤立结点图G,若存在一条路,经过图中每条边一次且仅仅一次,该条路称欧拉路,若存在一条回路,经过图中每边一次且仅仅一次,该回路称为欧拉回路。具有欧拉回路的图称为欧拉图。

定理:无向图G具有一条欧拉路,当且仅当G是连通的,且有0个或者是两个奇数度得结点。

推论:无向图G具有一条欧拉回路,当且仅当G是连通的,并且所有结点的度数均为偶数。

一笔画问题就是典型的这类问题:要判定一个图G是否可一笔画出,有两种情况, 从图中某一个结点出发,经过图G中每个边一次再回到该结点,或者是从G中某一个结点出发,经过G中每边一次且仅一次到达另一个结点,分别对应着欧拉回路和欧拉路的问题

 对有向图:

定义:给定有向图G,通过图中每边一次且仅一次的一条单向路(回路),称作单向欧拉路(回路)。

定理:有向图G具有单向欧拉路,当且仅当它是连通的,而且除两个结点外,每个结点的入度等于出度,但这两个结点中,一个结点的入度比出度大1,另一个结点的入度比出度小1。 

定理:有向图G具有一条单向欧拉回路,当且仅当是连通的,且每个结点入度等于出度。

HDOJ:http://acm.hdu.edu.cn/showproblem.php?pid=1878
#include <iostream>
#include <fstream>
using namespace std;

ifstream fin("in.txt");

#define LEN 1001
bool visited[LEN];
bool arc[LEN][LEN];
int degree[LEN];
int n,m;

void dfs(int v)         //深度优先遍历
{
    visited[v]=true;
    for(int i=1;i<=n;i++)
    {
        if(!visited[i] && arc[v][i])
        {
            dfs(i);
        }
    }
}

bool isConnected()        //查看遍历后结果
{
    for(int i=1;i<=n;i++)
    {
        if(!visited[i]){return false;}
    }
    return true;
}

bool isCircuit()        //通过度数是否为偶数判断欧拉回路
{
    for(int i=1;i<=n;i++)
    {
        if(degree[i]%2){return false;}
    }
    return true;
}

int main()
{
    int i,p,q;
    while(1)
    {
        memset(visited,0,LEN);
        memset(arc,0,sizeof(bool)*LEN*LEN);
        memset(degree,0,sizeof(int)*LEN);
        fin>>n>>m;
        if(n==0)break;
        for(i=0;i<m;i++)
        {
            fin>>p>>q;
            degree[p]++;degree[q]++;
            arc[p][q]=arc[q][p]=true;
        }
        dfs(1);
        if(!isConnected()){cout<<0<<endl;}
        else{
            if(isCircuit())cout<<1<<endl;
            else cout<<0<<endl;
            }
    }
    return 0;
}

你可能感兴趣的:(欧拉回路)