(POJ 1041)John's trip [无向欧拉图] 输出字典序最小的欧拉回路

来源:互联网 发布:计算机二级考试vb题库 编辑:程序博客网 时间:2024/04/29 02:38

John’s trip
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 9278 Accepted: 3112 Special Judge
Description

Little Johnny has got a new car. He decided to drive around the town to visit his friends. Johnny wanted to visit all his friends, but there was many of them. In each street he had one friend. He started thinking how to make his trip as short as possible. Very soon he realized that the best way to do it was to travel through each street of town only once. Naturally, he wanted to finish his trip at the same place he started, at his parents’ house.

The streets in Johnny’s town were named by integer numbers from 1 to n, n < 1995. The junctions were independently named by integer numbers from 1 to m, m <= 44. No junction connects more than 44 streets. All junctions in the town had different numbers. Each street was connecting exactly two junctions. No two streets in the town had the same number. He immediately started to plan his round trip. If there was more than one such round trip, he would have chosen the one which, when written down as a sequence of street numbers is lexicographically the smallest. But Johnny was not able to find even one such round trip.

Help Johnny and write a program which finds the desired shortest round trip. If the round trip does not exist the program should write a message. Assume that Johnny lives at the junction ending the street appears first in the input with smaller number. All streets in the town are two way. There exists a way from each street to another street in the town. The streets in the town are very narrow and there is no possibility to turn back the car once he is in the street
Input

Input file consists of several blocks. Each block describes one town. Each line in the block contains three integers x; y; z, where x > 0 and y > 0 are the numbers of junctions which are connected by the street number z. The end of the block is marked by the line containing x = y = 0. At the end of the input file there is an empty block, x = y = 0.
Output

Output one line of each block contains the sequence of street numbers (single members of the sequence are separated by space) describing Johnny’s round trip. If the round trip cannot be found the corresponding output block contains the message “Round trip does not exist.”
Sample Input

1 2 1
2 3 2
3 1 6
1 2 5
2 3 3
3 1 4
0 0
1 2 1
2 3 2
1 3 3
2 4 4
0 0
0 0
Sample Output

1 2 3 5 4 6
Round trip does not exist.
Source

Central Europe 1995

题意:
给你一个无向欧拉图,输出响应字典序最小的欧拉回路。

分析:
由于已知图是连通的,首先用度数是否全为偶数,判断图是否是欧拉图,然后,输出最小字典序回路。
其实就是每次都从小(环)往大的搜,先搜得一个最小序环,然后对环上的每一点进行搜索,其实对于欧拉图而言,每个点要么就只剩一个点,什么也搜不到了,要么还有一个环,只要把环上路径全都插入到对应位置上,用栈存路径,每次只有回溯到当前点,就是说当前点的后继都已经搜过了的时候,才把当前点入栈,这样一来倒着输出,就能得到一个欧拉回路,而且是最小字典序。

注意: 欧拉回路在dfs过程中,达到最底层后回溯时才开始确定欧拉回路路径

之前只写了一题没有理解好,就直接从小到大搜没有访问过的边,并依次输出,。。。。。竟然过了样例。。。。

AC代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <queue>#include <map>#include <vector>using namespace std;const int maxn = 50;struct edge{    int v,id;    edge(int vv,int iid)    {        v = vv;        id = iid;    }};vector<edge> g[maxn];int d[maxn];bool vis[2010];int ans[2010],num;int cmp(edge aa,edge bb){    if(aa.id > bb.id) return 1;    return 0;}void dfs_euler(int u){    for(int i=0;i<g[u].size();i++)    {        int id = g[u][i].id;        int v = g[u][i].v;        if(!vis[id])        {            vis[id] = true;            dfs_euler(v);            ans[num++] = id;        }    }}int main(){    int x,y,z,s,mm=0;    while(scanf("%d%d",&x,&y)!=EOF && x && y)    {        scanf("%d",&z);        s = min(x,y);        mm = 0;        mm = max(mm,x);        mm = max(mm,y);        for(int i=0;i<maxn;i++) g[i].clear();        memset(d,0,sizeof(d));        memset(vis,0,sizeof(vis));        d[x]++;        d[y]++;        g[x].push_back(edge(y,z));        g[y].push_back(edge(x,z));        while(scanf("%d%d",&x,&y) && x && y)        {            scanf("%d",&z);            d[x]++;            d[y]++;            g[x].push_back(edge(y,z));            g[y].push_back(edge(x,z));            mm = max(mm,x);            mm = max(mm,y);        }        bool eu = false;        for(int i=1;i<=mm;i++)        {            if(d[i] & 1)            {                eu = true;                break;            }        }        if(eu)        {            printf("Round trip does not exist.\n");            continue;        }        for(int i=1;i<=mm;i++) sort(g[i].begin(),g[i].end(),cmp);        num = 0;        dfs_euler(s);        printf("%d",ans[0]);        for(int i=1;i<num;i++)        {            printf(" %d",ans[i]);        }        printf("\n");    }    return 0;}
阅读全文
0 0
原创粉丝点击