->题目请戳这里<-
题目大意:一个小镇有m条街,n个交叉口,每条街上有john的一个朋友,现在john要拜访每个朋友1次,输出字典序最小的访问街道编号。起点是输入第一组数据最小的端点。
题目分析:典型的欧拉回路问题。先判断图是连通的并且所有点度数为偶数,因为这题是无向图,建图的时候每条边正反建一次。由于要字典序最小,所以要先dfs编号较小的街道,所以建图的时候稍微注意一下,我是先把所有的街道排序,先建编号大的边,保证dfs先遍历编号小的街道,从而答案保证字典序最小。详情请见代码:
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 20005; struct node { int from,to,id,next; bool vis; }edge[N]; int flag[N]; struct nd { int a,b,c; }lcm[N]; int num; int x,y; int set[50]; int degree[50]; int start,ind; int ans[N],top; int head[50]; int cmp(struct nd a,struct nd b) { if(a.a != b.a) return a.a < b.a; else return a.c > b.c; } void init() { int i; for(i = 1;i < 50;i ++) { head[i] = -1; set[i] = i; degree[i] = 0; } memset(flag,0,sizeof(flag)); num = top = 0; } int find(int a) { int root = a; while(root != set[root]) root = set[root]; int parent = set[a]; while(parent != root) { set[a] = root; a = parent; parent = set[a]; } return root; } void join(int a,int b) { int root_a = find(a); int root_b = find(b); set[root_b] = root_a; } int isok() { int i; int cnt = 0; //for(i = 1;i < 50;i ++) // printf("%d ",degree[i]); //printf("\n"); for(i = 1;i < 50;i ++) { if(set[i] == i && degree[i]) cnt ++; if(cnt > 1) return 0; if(degree[i] & 1) return 0; } return 1; } void build(int s,int e,int idx) { edge[num].from = s; edge[num].to = e; edge[num].id = idx; edge[num].vis = 0; edge[num].next = head[s]; head[s] = num ++; flag[idx] = 1; } void dfs(int u) { int i; for(i = head[u];i != -1;i = edge[i].next) { if(flag[edge[i].id]) { flag[edge[i].id] = 0; dfs(edge[i].to); ans[top ++] = edge[i].id; } } } int main() { int i; int t = 0; while(scanf("%d%d",&x,&y),(x + y)) { init(); scanf("%d",&ind); lcm[0].a = x; lcm[0].b = y; lcm[0].c = ind; lcm[1].a = y; lcm[1].b = x; lcm[1].c = ind; t = 2; start = x > y?y:x; //build(x,y,ind); degree[x] ++; degree[y] ++; join(x,y); while(scanf("%d%d",&x,&y),(x + y)) { scanf("%d",&ind); //build(x,y,ind); degree[x] ++; degree[y] ++; join(x,y); lcm[t].a = x; lcm[t].b = y; lcm[t ++].c = ind; lcm[t].a = y; lcm[t].b = x; lcm[t ++].c = ind; } sort(lcm,lcm + t,cmp); for(i = 0;i < t;i ++) { build(lcm[i].a,lcm[i].b,lcm[i].c); //printf("%d %d %d\n",lcm[i].a,lcm[i].b,lcm[i].c); } if(isok()) { dfs(start); //printf("%d\n",top); for(i = top - 1;i > 0;i --) printf("%d ",ans[i]); printf("%d\n",ans[i]); } else printf("Round trip does not exist.\n"); } return 0; } //372K 63MS