欧拉回路
定理:一个非平凡连通图G是Euler图当且仅当图G没有奇点。
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;
}