UASCO 3.3 Riding the Fences 騎馬修柵欄
阿新 • • 發佈:2018-12-11
題目大意
無向連通圖,求尤拉路徑。
樣例輸入&輸出
sample input
一個m,道路數,m對數,路的兩個端點。
9
1 2 2 3 3 4 4 2 4 5 2 5 5 6 5 7 4 6
sample output
字典序走的路徑
1 2 3 4 2 5 4 6 5 7
分析&反思
一開始大陸暴力dfs,4個點。後來瞭解到了新演算法 fleury 佛羅萊演算法。
目前還不大理解,但模板挺好背的。
先複習一下尤拉路徑和歐拉回路。
尤拉路徑:不重複走邊,走完所有的邊。
條件:度數為奇的點小於2,必從奇點出發,或必回到奇點。若有向圖則是入讀比出度大1和入度比出度大1的兩個點。
歐拉回路:不重複走邊,走完所有的邊,且回到出發點。
條件:無奇點。
此外,如果沒有奇點,從任意點出發都可以得到解。
fleury演算法就是。。。建立一個棧,先把起點放進去,開始迴圈。取棧頂彈出,如果無路可走(路都被走過了),就加入答案序列。若有路可走,dfs這個點,一路走並標記路,將走過的點加入棧,直到走不動(根據我的理解。。。dfs後可以得到一個橋對面的連通塊)。
算了我還是以後理解了再補吧。
程式碼
/* ID:changsz1 LANG:C++ TASK:fence */ #include<cstdio> #include<iostream> using namespace std; const int maxn = 503; int n1 = 1000000000, n2, m, map[maxn][maxn], du[maxn]; int ans[maxn*3], cnt; int stack[maxn*3], top; void dfs(int x) { stack[++top] = x; for(int i = n1; i <= n2; i++) { if(map[x][i]) { map[x][i]--; map[i][x]--; dfs(i); break; } } return; } void fleury(int u) { int flag = 0; stack[++top] = u; while(top) { flag = 0; u = stack[top--]; for(int v = n1; v <= n2; v++) { if(map[u][v]) { flag = 1; break; } } if(flag) dfs(u); else ans[++cnt] = u; } } int main() { freopen("fence.in", "r", stdin); freopen("fence.out", "w", stdout); scanf("%d", &m); for(int i = 1, u, v; i <= m; i++) { scanf("%d%d", &u, &v); map[u][v]++; map[v][u]++;//存在重邊 n1 = min(n1, min(u, v)); n2 = max(n2, max(v, u)); du[v]++; du[u]++; } int ji = 0; for(int i = n1; i <= n2; i++) if(du[i]%2 == 1) ji++; if(!ji) fleury(n1); else for(int i = n1; i <= n2; i++) if(du[i]%2 == 1) fleury(i); for(int i = m+1; i; i--) printf("%d\n", ans[i]); return 0; }