欧拉路AND欧拉回路

来源:互联网 发布:用python直接写utf 编辑:程序博客网 时间:2024/06/05 20:11

    定义:对于无孤立节点图G,若存在一条路经过图中每一条边且只经过一次,该条路称为欧拉路。若该路径为一个圈,则称为欧拉回路。

    欧拉路的判定

      (1)一个无向图存在欧拉路径,当且仅当该图是连通的,且只存在零个或两个奇数度的顶点。

      (2)一个有向图存在欧拉路径,当且仅当该图是连通的,且该图的所有顶点度数为0,或仅存在一个度数为1的顶点和一个度数为-1的顶点,其余点的度数均为0。

    欧拉回路的判定

      (1)一个无向图存在欧拉回路,当且仅当该图是连通的,且不存在奇数度的顶点。

      (2)一个有向图存在欧拉回路,当且仅当该图是连通的,且所有顶点的入度等于出度。

    对于度数的奇偶性,我们可以用非(!)运算来表示:1表示奇度,0表示偶度。接下来就是判断图的连通性了:搜索或者并查集都行,下面分别给出代码。


无向图的欧拉路径(题目链接:http://hihocoder.com/problemset/problem/1176 )

并查集实现代码如下:

#include <cstdio>#include <cstring>#include <iostream>using namespace std;const int maxn=10005;int ind[maxn];int par[maxn],ran[maxn];void init(int n){    for(int i=1;i<=n;i++)    {        par[i]=i;        ran[i]=1;    }}int Find(int x){    if(par[x]!=x)      return par[x]=Find(par[x]);    return x;}void Union(int x,int y){    x=Find(x);    y=Find(y);    if(x==y) return ;    if(ran[x]>ran[y])    {        par[y]=x;        ran[x]+=ran[y];    }    else    {        par[x]=y;        ran[y]+=ran[x];    }}int main(){    int n,m;    while(scanf("%d%d",&n,&m)!=-1)    {        init(n);        int u,v;        memset(ind,0,sizeof(ind));        for(int i=0;i<m;i++)        {            scanf("%d%d",&u,&v);            Union(u,v);            ind[u]=!ind[u]; //纪录每个顶点度数的奇偶性:1为奇度,0为偶度            ind[v]=!ind[v];        }        int sum_par=0,sum_ind=0;        for(int i=1;i<=n;i++)        {            if(par[i]==i) sum_par++;            if(ind[i]) sum_ind++;        }        if(sum_par>1)        {            puts("Part"); //不存在欧拉路            continue;        }        if(sum_ind==0||sum_ind==2) puts("Full"); //存在欧拉路        else puts("Part"); //不存在欧拉路    }    return 0;}



DFS实现代码如下:

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int maxn=10005;typedef struct{    int to,nex;}EDGE;EDGE edge[5*maxn];int head[maxn],cnt;int ind[maxn];bool vis[maxn];void add(int u,int v){    edge[cnt].to=v;    edge[cnt].nex=head[u];    head[u]=cnt++;}void dfs(int x){    vis[x]=true;    for(int i=head[x];i!=-1;i=edge[i].nex)      if(!vis[ edge[i].to ]) dfs(edge[i].to);}int main(){    int n,m;    while(scanf("%d%d",&n,&m)!=-1)    {        cnt=0;        memset(head,-1,sizeof(head));        memset(vis,false,sizeof(vis));        memset(ind,0,sizeof(ind));        for(int i=0;i<m;i++)        {            int u,v;            scanf("%d%d",&u,&v);            add(u,v);            ind[u]=!ind[u];            ind[v]=!ind[v];        }        dfs(1);        bool flag=false;        for(int i=1;i<=n;i++)          if(!vis[i]) flag=true;        if(flag)        {            puts("Part"); //不存在欧拉路            continue;        }        int sum_ind=0;        for(int i=1;i<=n;i++)          if(ind[i]) sum_ind++;        if(sum_ind==0||sum_ind==2) puts("Full");        else puts("Part");    }    return 0;}



对于欧拉回路,大体上和欧拉路的求解方法一致,只是在判断度数的奇偶性上略有差异。

0 0