歐拉迴路
題意:給一個有向圖,判斷是否是歐拉迴路,並且輸出路徑, 要求字典序最小。其中輸出時這個給的,x y z,x和y是點的編號(點數最多44),z是邊的編號(這邊是有編號的,邊數最大1995),其中輸出路徑不是輸出點而是輸出邊的編號,所以字典序最小是指邊的字典序最小。每組資料以0 0 結束。其中每組數組的第一行,兩個點x,y,選較小的那個作為起點
這題,圖是保證連通的,所以不需要判斷連通,所以判斷是不是歐拉圖,只需要看每個點的度是否都為偶數,不是的話則不存在歐拉迴路,是的話就存在歐拉迴路
輸出字典序最小的路徑,環一個建圖方法即可
e[k][0] , e[k][1]表示第k條邊的兩個頂點
我們用遞迴的方式去輸出路徑,從起點開始,然後枚舉邊,從編號最小的邊開始枚舉,這樣就能保證字典序最小
#include <iostream>#include <cstdio>#include <cstring>#include <stack>using namespace std;#define N 50#define M 2010int node,edge,sp,Max;int e[M][2],de[M];bool used[M];stack<int>sta;void dfs(int u){ for(int k=1; k<=edge; k++) if(!used[k]) { int v; if(e[k][0] == u) v = e[k][1]; else if(e[k][1] == u) v = e[k][0]; else continue; used[k] = true; dfs(v); sta.push(k); }}void solve(){ while(!sta.empty()) sta.pop(); memset(used,false,sizeof(used)); dfs(sp); bool first = true; while(!sta.empty()) { if(!first) cout << " "; cout << sta.top(); first = false; sta.pop(); } cout << endl;}int main(){ int u,v,m; while(cin >> u >> v) { if(u == 0 && v == 0) break; memset(de,0,sizeof(de)); sp = min(u,v); Max = max(u,v); cin >> m; e[m][0] = u; e[m][1] = v; de[u]++; de[v]++; edge = 1; while(cin >> u >> v) { if(u == 0 && v == 0) break; Max = max(Max,u); Max = max(Max,v); cin >> m; e[m][0] = u; e[m][1] = v; de[u]++; de[v]++; edge++; } int ok = 1; for(int i=1; i<=Max; i++) if(de[i] & 1) { ok = 0; break;} if(!ok) { cout << "Round trip does not exist." << endl; continue; } solve(); } return 0;}