POJ 1041 尤拉路
阿新 • • 發佈:2018-11-13
題意:多組資料,輸入x,y,z,表示結點x和結點y之間有一條序號為z的邊,如果這個無向圖中存在尤拉路,就字典序最小的尤拉路,如果不存在尤拉路就輸出“Round trip does not exist. "。當輸入0 0表示一組資料輸入結束,題目保證了圖的連通性。
Solution:首先根據尤拉路的定義判斷是否存在尤拉路,如果存在的話再求字典序最小的尤拉路,一定是以邊1為起始的尤拉路,然後將每個結點的邊按序號從小到大排序,從而保證dfs的時候得到的是字典序最小的尤拉路。
AC_Code:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <queue> #include <algorithm> #define ll long long using namespace std; const int inf=0x3ffffff; const int MAXN = 2003; const int MAXM = 1000005; const double eps = 1e-6; vector<pair<int, int> > adj[MAXN]; //adj[i][j].first 表示節點i的第j條邊的序號 //adj[i][j].second 表示節點i的第y條邊的終點 bool vis[MAXM]; void add(int x, int y, int z) //x和y之間有條邊,序號為z { adj[x].push_back(make_pair(z, y)); adj[y].push_back(make_pair(z, x)); } vector<int> path; void dfs(int u) { for (int i = 0; i < adj[u].size(); i++) { if (!vis[adj[u][i].first]) { vis[adj[u][i].first] = true; dfs(adj[u][i].second); path.push_back(adj[u][i].first); } } } bool solve() { int origin = -1; for (int i = 0; i < MAXN; i++) { if (adj[i].size()) { // 無向圖中存在歐拉回路的條件是各個節點度都是偶數 if (adj[i].size() % 2 == 1) return false; if (origin == -1) origin = i; sort(adj[i].begin(), adj[i].end()); // 排序之後,保證最先找到的那條路是字典序最小的 } } path.clear(); memset(vis, false, sizeof(vis)); if (origin != -1) dfs(origin); reverse(path.begin(), path.end()); return true; } int main() { int i, j, k; int x, y, z; while(1) { for (i = 0; i < MAXN; i++) adj[i].clear(); scanf("%d%d", &x, &y); if (x == 0 && y == 0) break; do { scanf("%d", &z); add(x, y, z); scanf("%d%d", &x, &y); } while(x && y); if (solve()) { for (int i = 0; i < path.size(); i++) printf("%d ", path[i]); puts(""); } else puts("Round trip does not exist."); } return 0; }