您的位置:首页 > 其它

欧拉路AND欧拉回路

2015-08-15 21:06 197 查看
定义:对于无孤立节点图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;
}


对于欧拉回路,大体上和欧拉路的求解方法一致,只是在判断度数的奇偶性上略有差异。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: