Description
欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路?
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
题义就是在给定的图中判定是否存在欧拉回路。
图G的一个回路,若它恰通过G中每条边一次,则称该回路为欧拉(Euler)回路。
具有欧拉回路的图称为欧拉图(简称E图)。
这里总结下各种图的判定的方法:
1.无向图中:所给定的图为连通图,且所有节点的度为偶数;
2.有向图中:所给定的图为连通图,且所有节点的度为零。
#include <stdio.h>
#include <string.h>
int cnt[1001];
int pre[1001];
int find(int x)
{
int r=x;
while(r!=pre[r])
{
r=pre[r];
}
return r;
}
int main()
{
int n,m;
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break;
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;i++)
{
pre[i]=i;
}
scanf("%d",&m);
while(m--)
{
int a,b;
scanf("%d%d",&a,&b);
cnt[a]++;
cnt[b]++;
int fx=find(a);
int fy=find(b);
if(fx!=fy)
{
pre[fx]=fy;
}
}
int root=0;
int du=0;
for(int i=1;i<=n;i++)
{
if(cnt[i]%2==0)
{
du++;
}
if(i==pre[i])
{
root++;
}
}
if(du==n&&root==1)
{
printf("1\n");
}
else
{
printf("0\n");
}
}
return 0;
}
用深搜也能做:
#include<iostream>
using namespace std;
#define N 1001
int map[N][N];
bool visited[N];
int cheak[N];
int n,i;
void init()
{
memset(visited,0,sizeof(visited));
memset(map,0,sizeof(map));
memset(cheak,0,sizeof(cheak));
}
void DFS(int k)
{
visited[k]=1;
for(i=1;i<=n;i++)
if(!visited[i]&&map[k][i])
DFS(i);
return;
}
int cheakk()
{
for(i=1;i<=n;i++)
if(cheak[i]%2)
return 0;
return 1;
}
int main()
{
int m,i,a,b;
while(cin>>n&&n)
{
cin>>m;
init();
for(i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
map[a][b]=map[b][a]=1;
cheak[a]++;
cheak[b]++;
}
DFS(1);
for(i=1;i<=n;i++)
if(!visited[i])
break;
if(i>n&&cheakk())
printf("1\n");
else
printf("0\n");
}
return 0;
}