Problem 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中不存在奇度頂點。請看代碼:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<queue>
using namespace std ;
const int MAXN = 1005 ;
int set[MAXN] ;
int d[MAXN] ; // 存頂點的度
inline void RD (int &a) // 輸入優化
{
a = 0 ;
char t ;
while ((t = getchar()) && t >= '0' && t <= '9')
{
a = a * 10 + t - '0' ;
}
}
int find(int x) // 並查集
{
int r = x ;
while ( r != set[r] )
{
r = set[r] ;
}
return r ;
}
int main()
{
int n , m ;
while (1)
{
RD(n) ;
if(n == 0)
break ;
memset(set , 0 , sizeof(set)) ;
memset(d , 0 , sizeof(d)) ;
RD(m) ;
int i ;
for(i = 1 ; i <= n ; i ++) // 初始化並查集
{
set[i] = i ;
}
for(i = 0 ; i < m ; i ++)
{
int a , b ;
RD(a) ;
RD(b) ;
d[a] ++ ;
d[b] ++ ;
int ta , tb ;
ta = find(a) ;
tb = find(b) ;
if(ta < tb)
{
set[tb] = ta ;
}
else
set[ta] = tb ;
}
int sumj = 0 ;
int fz = 0 ;
for(i = 1 ; i <= n ; i ++)
{
if(set[i] == i)
{
fz ++ ;
}
if(d[i] % 2 == 1)
{
sumj ++ ;
}
}
if(fz > 1 || sumj > 0)
{
printf("0\n") ;
}
else
{
printf("1\n") ;
}
}
return 0 ;
}