UVa302 - John's trip(并查集、欧拉回路、DFS)

John's trip 

Little Johnny has got a new car. He decided to drive around the town tovisit his friends. Johnnywanted to visit all his friends, but there was many of them. In each streethe had one friend. He startedthinking how to make his trip as short as possible. Very soon he realizedthat the best way to do it was totravel through each street of town only once. Naturally, he wanted tofinish his trip at the same place hestarted, at his parents' house.

The streets in Johnny's town were named by integer numbers from 1 to n,n < 1995. The junctionswere independently named by integer numbers from 1 tom,tex2html_wrap_inline32 .All junctions in the town had different numbers. Each street wasconnecting exactly two (not necessarily different) junctions.No two streets in the town had the same number. He immediately started toplan his round trip. If therewas more than one such round trip, he would have chosen the one which,when written down as a sequenceof street numbers is lexicographically the smallest.

But Johnny was notable to find even one such round trip.Help Johnny and write a program which finds the desired shortest roundtrip. If the round trip doesnot exist the program should write a message. Assume that Johnny lives atthe junction ending the 1st street inputwith smaller number. All streets in the town are two way. Thereexists a way from each street toanother street in the town. The streets in the town are very narrow andthere 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 containsthree integersx,y, z, where x > 0 and y > 0 are the numbers ofjunctions which are connected by the streetnumberz. The end of the block is marked by the line containingx = y = 0.At the end of the input file there is an empty block,x = y = 0.

Output

The output file consists of 2 line blocks corresponding to the blocks ofthe input file. The first line ofeach block contains the sequence of street numbers (single members of thesequence are separated by space)describing Johnny's round trip. If the round trip cannot be found thecorresponding output block containsthe message ``Round trip does not exist.''. The second line of eachblock is empty.

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.

这个问题理解了好长时间,以为是从街道号最小的一个端点为起点,Assume that Johnny lives atthe junction ending the 1st street inputwith smaller number.原来是说是以第一个输入的最小的junction作为起点

这个问题主要是欧拉回路的问题,1、用并查集判断是不是连通的;2、每个点的度数是不是偶数;3、用dfs打印欧拉回路路径

#include <cstdio>
#include <vector>
#include <utility>
#include <cstring>
#include <climits>
#include <algorithm>

using namespace std;

const int N = 2000;

int deg[N];
vector< pair<int, int> > adjList[N];
bool vis[N];
int ans[N];
int top;
int start;

bool input();
void add(int x, int y, int z);
void solve();
void dfs(int u);

int main()
{
#ifndef ONLINE_JUDGE
    freopen("d:\\OJ\\uva_in.txt", "r", stdin);
#endif

    while (input()) {
        solve();
    }
    return 0;
}

bool input()
{
   int x, y, z;

   scanf("%d%d", &x, &y);
   if (x == 0 && y == 0) return false;

	start = min(x, y);
   for (int i = 0; i < N; i++) adjList[i].clear();
   memset(deg, 0x00, sizeof(deg));

   while (1) {
       scanf("%d", &z);
       add(x, y, z);
       deg[x]++;
       deg[y]++;

       scanf("%d%d", &x, &y);
       if (x == 0 && y == 0) break;
   }

   return true;
}

void add(int x, int y, int z)
{
    adjList[x].push_back(make_pair(z, y));;
    adjList[y].push_back(make_pair(z, x));;
}

void solve()
{
    bool ok = true;
    for (int i = 0; i < N; i++) {
        if (!adjList[i].empty()) {
            if (deg[i] & 1) {
                ok = false;
                break;
            }
            sort(adjList[i].begin(), adjList[i].end());
        }
    }

    if (!ok) {
        printf("Round trip does not exist.\n\n");
        return;
    }

    top = 0;
    memset(vis, false, sizeof(vis));

    dfs(start);
    for (int i = top - 1; i >= 0; i--) {
        printf("%d%s", ans[i], i ? " ":"\n\n");
    }
}

void dfs(int u)
{
    for (size_t i = 0; i < adjList[u].size(); i++) {
        if (!vis[adjList[u][i].first]) {
            vis[adjList[u][i].first] = true;
            dfs(adjList[u][i].second);
            ans[top++] = adjList[u][i].first;
        }
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值