歐拉回路與歐拉路 之 一筆畫問題


一筆畫問題
  如果一個圖存在一筆畫,則一筆畫的路徑叫做歐拉路,如果最后又回到起點,那這個路徑叫做歐拉回路。
  我們定義奇點是指跟這個點相連的邊數目有奇數個的點。對於能夠一筆畫的圖,我們有以下兩個定理。
定理1:存在歐拉路的條件:圖是連通的,有且只有2個奇點。
定理2:存在歐拉回路的條件:圖是連通的,有0個奇點。
兩個定理的正確性是顯而易見的,既然每條邊都要經過一次,那么對於歐拉路,除了起點和終點外,每個點如果進入了一次,顯然一定要出去一次,顯然是偶點。對於歐拉回路,每個點進入和出去次數一定都是相等的,顯然沒有奇點。
一筆畫性質:
■⒈凡是由偶點組成的連通圖,一定可以一筆畫成。畫時可以把任一偶點為起點,最后一定能以這個點為終點畫完此圖。
■⒉凡是只有兩個奇點的連通圖(其余都為偶點),一定可以一筆畫成。畫時必須把一個奇點為起點,另一個奇點為終點。
■⒊其他情況的圖都不能一筆畫出。(奇點數除以二便可算出此圖需幾筆畫成。)
  求歐拉路的算法很簡單,使用深度優先遍歷即可。
  根據一筆畫的兩個定理,如果尋找歐拉回路,對任意一個點執行深度優先遍歷;找歐拉路,則對一個奇點執行DFS,時間復雜度為O(m+n),m為邊數,n是點數。
l樣例輸入:第一行n,m,有n個點,m條邊,以下m行描述每條邊連接的兩點。
l    5 5
l    1 2
l    2 3
l    3 4
l    4 5
l    5 1
l樣例輸出:歐拉路或歐拉回路
l    1 5 4 3 2 1
 
歐拉路:
 1 //歐拉路 
 2 
 3 #include<iostream>
 4 #include<cstdio>
 5 using namespace std;
 6 int maps[1001][1001];
 7 int flag[1001];
 8 int tot,n,m;
 9 int ans[1001],p=0;
10 void dfs(int num){
11     for(int i=1;i<=m;i++)
12     if(maps[num][i]==1)
13     {
14         maps[num][i]=0;
15         maps[i][num]=0;
16         dfs(i);
17         ans[++p]=i;
18     }
19 }
20 int main()
21 {
22     int a,b,flag1=0,start=1;
23     scanf("%d%d",&m,&n);
24     for(int i=1;i<=n;i++)
25     {
26         scanf("%d%d",&a,&b);
27         maps[a][b]=1;
28         maps[b][a]=1;
29         flag[a]++;
30         flag[b]++;
31     }
32     for(int i=1;i<=n;i++)
33     {
34         if(flag[i]%2!=0)
35         {
36             if(flag1==0)
37             start=i;
38             flag1++;
39         }
40         if(flag1>2)
41         {
42             printf("Impossible");
43             return 0;
44         }
45     }
46     dfs(start);//必須從奇點開始搜 
47     for(int i=1;i<=p;i++)
48     printf("%d ",ans[i]);
49     return 0;    
50 }

歐拉回路:

 

似乎比歐拉路還水:從1開始搜的;

 1 //歐拉回路 
 2 
 3 #include<iostream>
 4 #include<cstdio>
 5 using namespace std;
 6 int maps[1001][1001];
 7 int flag[1001];
 8 int n,m;
 9 int ans[1001],p=0;
10 void dfs(int num){//搜哦搜 
11     for(int i=1;i<=m;i++)
12     if(maps[num][i]==1)
13     {
14         maps[num][i]=0;
15         maps[i][num]=0;
16         dfs(i);
17         ans[++p]=i;
18     }
19 }
20 int main()
21 {
22     int a,b,flag1=0;
23     scanf("%d%d",&m,&n);
24     for(int i=1;i<=n;i++)
25     {
26         scanf("%d%d",&a,&b);
27         maps[a][b]=1;
28         maps[b][a]=1;
29         flag[a]++;
30         flag[b]++;
31     }
32     for(int i=1;i<=n;i++)
33     {
34         if(flag[i]%2!=0)
35         {
36             printf("Impossible");
37             return 0;
38         }
39     }
40     dfs(1);//滿足的話從哪個點搜都可以; 
41     for(int i=1;i<=p;i++)
42     printf("%d ",ans[i]);
43     printf("%d ",1);
44     return 0;    
45 }

 


免責聲明!

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



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