poj 1041 John's trip
欧拉回路
题意:给一个有向图,判断是否是欧拉回路,并且输出路径, 要求字典序最小。其中输出时这个给的,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 2010 int 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; }