欧拉回路
定理:一个非平凡连通图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;
}