题目:https://pintia.cn/problem-sets/15/problems/859
输入n和m,表示有n个点和m条边,输入m条边的两点下标,判断给出的无向图是否存在欧拉回路;
思路:
欧拉回路的条件有两点:图是否连通,图的每个点的边的总数是否是偶数;
判断图是否连通通过并查集来并入各个点,若只有一个根结点则连通,或者DFS搜索一遍,若所有点被访问则联通。
并查集:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 1001
int root[MAX];
int cnt[MAX];
int FindRoot(int x){ //求根结点
if(root[x]==x)
return x;
return root[x]=FindRoot(root[x]);
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
cnt[i]=0;
root[i]=i;
}
for(int i=0;i<m;i++){
int p1,p2;
scanf("%d%d",&p1,&p2);
int r1=FindRoot(p1),r2=FindRoot(p2);
if(r1!=r2)
root[r2]=r1;
cnt[p1]++; cnt[p2]++; //计算每个点的边数
}
int ant=0;
int flag=1;
for(int i=0;i<n;i++)
if(root[i]==i) //计算有多少个根结点
ant++;
if(ant==1){
for(int i=1;i<=n;i++){
if(cnt[i]%2){
flag=0;
break;
}
}
if(flag) printf("1\n");
else printf("0\n");
}
else printf("0\n");
}
DFS搜索
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 1001
int point[MAX][MAX];
int visited[MAX]={0};
int cnt[MAX]={0};
void dfs(int i,int n){
visited[i]=1;
for(int j=1;j<=n;j++){
if(point[i][j]&&!visited[j])
dfs(j,n);
}
}
int main(){
int n,m,flag=1;;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
point[i][j]=0;
for(int i=0;i<m;i++){
int p1,p2;
scanf("%d%d",&p1,&p2);
point[p1][p2]=1; point[p2][p1]=1;
cnt[p1]++; cnt[p2]++;
}
dfs(1,n);
for(int i=1;i<=n;i++){
if(visited[i]==0||cnt[i]%2==1){
flag=0;
break;
}
}
printf("%d\n",flag);
}