洛谷P2731《騎馬修柵欄 Riding the Fences》
阿新 • • 發佈:2020-10-14
原更新日期:2019-01-20 23:46:46
尤拉圖板子題
題目背景
Farmer John每年有很多柵欄要修理。他總是騎著馬穿過每一個柵欄並修復它破損的地方。
題目描述
John是一個與其他農民一樣懶的人。他討厭騎馬,因此從來不兩次經過一個柵欄。你必須編一個程式,讀入柵欄網路的描述,並計算出一條修柵欄的路徑,使每個柵欄都恰好被經過一次。John能從任何一個頂點(即兩個柵欄的交點)開始騎馬,在任意一個頂點結束。
每一個柵欄連線兩個頂點,頂點用1到500標號(雖然有的農場並沒有500個頂點)。一個頂點上可連線任意多(>=1)個柵欄。兩頂點間可能有多個柵欄。所有柵欄都是連通的(也就是你可以從任意一個柵欄到達另外的所有柵欄)。
你的程式必須輸出騎馬的路徑(用路上依次經過的頂點號碼錶示)。我們如果把輸出的路徑看成是一個500進位制的數,那麼當存在多組解的情況下,輸出500進製表示法中最小的一個 (也就是輸出第一位較小的,如果還有多組解,輸出第二位較小的,等等)。
輸入資料保證至少有一個解。
輸入輸出格式
輸入格式
第1行: 一個整數F(1 <= F <= 1024),表示柵欄的數目
第2到F+1行: 每行兩個整數i, j(1 <= i,j <= 500)表示這條柵欄連線i與j號頂點。
輸出格式
輸出應當有F+1行,每行一個整數,依次表示路徑經過的頂點號。注意資料可能有多組解,但是隻有上面題目要求的那一組解是認為正確的。
輸入輸出樣例
輸入樣例
9
1 2
2 3
3 4
4 2
4 5
2 5
5 6
5 7
4 6
輸出樣例
1
2
3
4
2
5
4
6
5
7
說明
題目翻譯來自NOCOW。
USACO Training Section 3.3
解題思路
「使每個柵欄都恰好被經過一次」
妥妥的尤拉路板子題啊
沒學過的看這裡
程式碼實現
/* -- Basic Headers -- */ #include <iostream> #include <cstdio> #include <cstring> #include <cctype> #include <algorithm> /* -- STL Iterators -- */ #include <vector> #include <string> #include <stack> #include <queue> /* -- External Headers -- */ #include <map> #include <cmath> /* -- Defined Functions -- */ #define For(a,x,y) for (int a = x; a <= y; ++a) #define Forw(a,x,y) for (int a = x; a < y; ++a) #define Bak(a,y,x) for (int a = y; a >= x; --a) namespace FastIO { inline int getint() { int s = 0, x = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') x = -1; ch = getchar(); } while (isdigit(ch)) { s = s * 10 + ch - '0'; ch = getchar(); } return s * x; } inline void __basic_putint(int x) { if (x < 0) { x = -x; putchar('-'); } if (x >= 10) __basic_putint(x / 10); putchar(x % 10 + '0'); } inline void putint(int x, char external) { __basic_putint(x); putchar(external); } } namespace Solution { const int MAXN = (500 + 10) << 1; int G[MAXN][MAXN], n, degree[MAXN]; int __MAX_NODE = -1, __MIN_NODE = 0x7f7f7f7f; std::stack<int> ans; void addEdge(int from, int to) { ++G[from][to]; ++G[to][from]; ++degree[from]; ++degree[to]; } void Hierholzer(int s) { for (int t = __MIN_NODE; t <= __MAX_NODE; ++t) { if (G[s][t]) { --G[s][t]; --G[t][s]; Hierholzer(t); } } ans.push(s); } } signed main() { #define HANDWER_FILE #ifndef HANDWER_FILE freopen("testdata.in", "r", stdin); freopen("testdata.out", "w", stdout); #endif using namespace Solution; using namespace FastIO; n = getint(); For (i, 1, n) { int prev = getint(); int next = getint(); addEdge(prev, next); __MAX_NODE = std::max(__MAX_NODE, std::max(prev, next)); __MIN_NODE = std::min(__MIN_NODE, std::min(prev, next)); } int start = 1, flag = 0; for (int i = 1; i <= __MAX_NODE; ++i, ++start) { if (degree[i] != 0 && degree[i] % 2 == 1) { flag = 1; break; } } if (flag) Hierholzer(start); else Hierholzer(1); while (!ans.empty()) { putint(ans.top(), '\n'); ans.pop(); } return 0; }