初學算法之最基礎的歐拉回路


須知:

圖中的:所謂頂點的度(degree),就是指和該頂點相關聯的邊數。

有向圖中,度又分為入度和出度。
 
入度 (in-degree) :以某頂點為弧頭,終止於該頂點的弧的數目稱為該頂點的入度。
 
出度 (out-degree) 是指以某頂點為弧尾,起始於該頂點的弧的數目。
 
在某頂點的入度和出度的和稱為該頂點的度
 
定義:
歐拉回路:每條邊恰好只走一次,並能回到出發點的路徑

歐拉路徑:經過每一條邊一次,但是不要求回到起始點
 
歐拉回路存在性的判定:

一、無向圖
每個頂點的度數都是偶數,則存在歐拉回路。

二、有向圖(所有邊都是單向的)
每個節頂點的入度都等於出度,則存在歐拉回路。

歐拉路徑存在性的判定:

一。無向圖
一個無向圖存在歐拉路徑,當且僅當   該圖所有頂點的度數為偶數   或者  除了兩個度數為奇數外其余的全是偶數。

二。有向圖
一個有向圖存在歐拉路徑,當且僅當 該圖所有頂點的度數為零     或者 一個頂點的度數為1,另一個度數為-1,其他頂點的度數為0。

例:NYOJ 42 一筆畫問題

一筆畫問題

時間限制: 3000 ms  |  內存限制:65535 KB
難度: 4
 
描述

zyc從小就比較喜歡玩一些小游戲,其中就包括畫一筆畫,他想請你幫他寫一個程序,判斷一個圖是否能夠用一筆畫下來。

規定,所有的邊都只能畫一次,不能重復畫。

 

 
輸入
第一行只有一個正整數N(N<=10)表示測試數據的組數。
每組測試數據的第一行有兩個正整數P,Q(P<=1000,Q<=2000),分別表示這個畫中有多少個頂點和多少條連線。(點的編號從1到P)
隨后的Q行,每行有兩個正整數A,B(0<A,B<P),表示編號為A和B的兩點之間有連線。
輸出
如果存在符合條件的連線,則輸出"Yes",
如果不存在符合條件的連線,輸出"No"。
樣例輸入
2
4 3
1 2
1 3
1 4
4 5
1 2
2 3
1 3
1 4
3 4
樣例輸出
No
Yes
來源
[張雲聰]原創
上傳者
張雲聰
 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 const int Max = 1111;
 5 int map[Max][Max];
 6 int vis[Max],coun[Max];
 7 int n,p,q,f;
 8 void dfs(int a)
 9 {
10     vis[a]=1;
11     for(int i=1;i<=p;i++)
12     {
13         if(map[a][i])
14         {
15             coun[a]++;   //每個頂點的度數 
16             if(!vis[i])
17             dfs(i);
18         }
19     }
20 }
21 int main()
22 {
23     scanf("%d",&n);
24     while(n--)
25     {
26         f=0;
27         memset(coun,0,sizeof(coun));
28         memset(map,0,sizeof(map));
29         memset(vis,0,sizeof(vis));
30         int a,b;
31         scanf("%d %d",&p,&q);
32         for(int i=0;i<q;i++)
33         {
34             scanf("%d %d",&a,&b);
35             map[a][b]=1;
36             map[b][a]=1;
37         }
38         dfs(1);
39         for(int k=1;k<=p;k++)
40         if(!vis[k])
41         {
42             f=1;
43             break;
44         }
45         if(f)
46         printf("No\n");
47         else
48         {
49             int j=0;
50             for(int k=1;k<=p;k++)
51             {
52                 if(coun[k]%2!=0)     //記錄度數為奇數的個數 
53                 j+=1;
54             }
55                 if(j==2||j==0)   //如果度數為奇數的為兩個,則這倆個是起點和終點 
56                 printf("Yes\n"); //如果度數為奇數的為0個,則所有點可為起點 
57                 else
58                 printf("No\n");
59         }
60     }
61     return 0;
62 }
View Code

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM