高棕櫚的意外收穫
題目連結
講義連結
這一題就是按照字典序print出尤拉路徑,特別用鄰接矩陣來存圖是因為要按照字典序輸出,如果用鏈結串列來存還要花時間排序,因此用大一點的空間來節省時間
尤拉路徑也是一筆畫問題,每一個節點一定會有進有出,因此原先的無向圖上每一點一定度數為偶數,若有奇點則選擇其中一個奇點作為起點,當奇點數量超過兩個則代表無解。我們將DFS的過程中離開當前節點的順序紀錄起來,逆序輸出就是一組合法歐拉迴路的解了!
實作程序
1. 判斷奇點個數,若奇點個數k:
- k > 2,那麼無解
- k = 2,則選擇其中一個奇點作為起點
- k = 0,則選擇任意一個點作為起點
2. DFS 執行下列步驟
若當前節點還有尚未走過的邊,那麼拜訪該邊,並在拜訪完後輸出該邊
否則離開當前結點
3. 若還有節點尚未拜訪,則無解
4. 否則輸出順序即為一組解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| #include <bits/stdc++.h> #define N 501 using namespace std; int n,Edge[N][N],ans[1025],ind = 0;
void DFS(int cur){ for(int i=1;i<=500;i++){ if(Edge[cur][i]){ Edge[cur][i]--;Edge[i][cur]--; DFS(i); } } ans[ind++] = cur; }
signed main(){ cin>>n; memset(Edge, 0, sizeof(Edge)); for(int i=0;i<n;i++){ int a,b;cin>>a>>b; Edge[a][b]++; Edge[b][a]++; } int start = 1; for(int i=1;i<=500;i++){ int sum = 0; for(int j=1;j<=500;j++){ sum+=Edge[i][j]; } if(sum%2!=0){ start = i; break; } } DFS(start); for(int i=ind-1;i>=0;i--)cout<<ans[i]<<endl; }
|