數據結構實驗之圖論八:歐拉回路
Time Limit: 1000 ms Memory Limit: 65536 KiB
Problem Description
在哥尼斯堡的一個公園裏,有七座橋將普雷格爾河中兩個島及島與河岸連接起來。
能否走過這樣的七座橋,並且每橋只走一次?瑞士數學家歐拉最終解決了這個問題並由此創立了拓撲學。歐拉通過對七橋問題的研究,不僅圓滿地回答了哥尼斯堡七橋問題,並證明了更爲廣泛的有關一筆畫的三條結論,人們通常稱之爲歐拉定理。對於一個連通圖,通常把從某結點出發一筆畫成所經過的路線叫做歐拉路。人們又通常把一筆畫成回到出發點的歐拉路叫做歐拉回路。具有歐拉回路的圖叫做歐拉圖。
你的任務是:對於給定的一組無向圖數據,判斷其是否成其爲歐拉圖?
Input
連續T組數據輸入,每組數據第一行給出兩個正整數,分別表示結點數目N(1 < N <= 1000)和邊數M;隨後M行對應M條邊,每行給出兩個正整數,分別表示該邊連通的兩個結點的編號,結點從1~N編號。
Output
若爲歐拉圖輸出1,否則輸出0。
Sample Input
1 6 10 1 2 2 3 3 1 4 5 5 6 6 4 1 4 1 6 3 4 3 6
Sample Output
1
歐拉回路基本算法就是進行深搜,但是很有可能只訪問了圖的一部分而提前返回起點,如果從起點出發的所有邊均已用完,那麼圖中就會有部分遍歷不到。最容易的補救方法就是找出有尚未訪問的邊的路徑上的第一個頂點,並執行一次深度優先搜索,這將給出另外一個迴路,把它拼接到原來的迴路上。繼續該過程直到所有的邊都被遍歷到爲止。
然鵝,此題僅僅讓你判斷,並查集就可以輕鬆解決,度數都爲偶數且在一個集合裏
#include <iostream>
using namespace std;
typedef int ElementType;
typedef struct
{
ElementType Data;
int Parent;
}SetType;
SetType S[10001];
int MaxSize;
int Find ( SetType *S, ElementType X )
{
int i = 0;
while( i<MaxSize && S[i].Data != X )
i++;
while( S[i].Parent >= 0 )
i = S[i].Parent ;
return i;
}
void Union ( SetType *S, ElementType X1, ElementType X2 )
{
int Root1, Root2;
Root1 = Find ( S, X1 );
Root2 = Find ( S, X2 );
if( Root1 != Root2 )
S[Root2].Parent = Root1;
}
int sum[10001];
int main()
{
int t;
cin >> t;
while ( t-- )
{
int num = 0;
int n, m, i;
cin >> n >> m;
for( i=1; i<=n; i++ )
{
S[i].Parent = -1;
S[i].Data = i;
}
MaxSize = n;
for( i=0; i<m; i++ )
{
int a, b;
cin >> a >> b;
Union( S, a, b );
sum[a]++;
sum[b]++;
}
for( i=0; i<n; i++ )
{
if(S[i].Parent == -1)
num++;
}
int flag = 1;
for( i=0; i<n; i++ )
if(sum[i] % 2 == 1)
{
flag = 0;
break;
}
if( num == 1 && flag == 1 )
cout << 1 << endl;
else
cout << 0 << endl;
}
return 0;
}