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 ; }