poj1041 John's trip (无向图求欧拉回路方案)

John‘s trip

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 5950   Accepted: 1946   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

<span style="font-size: 14px;">1 2 3 5 4 6
</span><p style="font-size: 14px;">Round trip does not exist.</p><p style="font-size: 14px;">
</p><p><strong><span style="font-size:18px;">此题目从半上午做到这时候,首先把算法弄懂了,然后就是找bug将近三个小时!!bug?判断相等的时候要用两个等号 活生生少写一个!!!!醉了~。核心思想是在判断完有欧拉回路的情况下,这个可以从所有点度数都是偶数的充分条件来判定,然后从标号最小的边开始dfs,因为程序里有个对邻接表排序的过程你,那么必然之后沿着边的标号上升的dfs过程。遇到走不通就回溯,那么此时必然还要存在环,否则不会出现走不通,那时应该全图是一个环才对。遇到最小序环(假设存在)且无法继续dfs回溯的时候,回溯出来的那条边必然到最后是欧拉回路最后一条边,直接push,否则就会出现沿着欧拉回路走的时候“过快”的回到原点了。遇到最小序环且无法走通的情况下,此时就要从最小序环遍历各点dfs并按照边标号上升的顺序深搜其他环,那么path里面到最后就保存的是欧拉路径的 逆序,reverse一下就么么哒了~</span></strong></p><p style="font-size: 14px;"><pre name="code" class="cpp">#include<iostream>
#include<sstream>
#include<algorithm>
#include<cstdio>
#include<string.h>
#include<cctype>
#include<string>
#include<cmath>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
using namespace std;

//input: adj 全局变量,adj【i】表示从结点i连出的所有边
//判断是否有解。有向无向皆可,path(全局)保存欧拉回路。
const int maxn=2000;
const int maxm=1000000;
int father[maxn];
vector< pair<int,int > > adj[maxn];
bool vis[maxm];

int getFather(int x)
{
     return x==father[x]?x:father[x]=getFather(father[x]);
//    int root=a;
//    int temp;
//    while(father[root]!=root)
//        root=father[root];
//    while(father[a]!=root)
//    {
//        temp=a;
//        a=father[a];
//        father[temp]=root;
//    }
}

void add (int x,int y,int 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 it=0; it<adj[u].size(); it++)
        if(!vis[adj[u][it].first])
        {
            vis[adj[u][it].first]=1;
            dfs(adj[u][it].second);
            path.push_back(adj[u][it].first);
        }
}

bool solve()
{
    for(int i=0; i<maxn; i++)
        father[i]=i;
    for(int i=0; i<maxn; i++)
    {
        for(int j =0; j < adj[i].size() ; ++j)
        {
            father[getFather(i)]=getFather(adj[i][j].second);
        }
    }
    int origin=-1;
    for(int i=0; i<maxn; i++)
        if(adj[i].size())
        {
            if(adj[i].size()%2==1)return 0;
            if(origin==-1)origin=i;
            if(getFather(i)!=getFather(origin))return 0;
            sort(adj[i].begin(),adj[i].end());
        }
    path.clear();
    memset(vis,0,sizeof(vis));
    if(origin!=-1)dfs(origin);
    reverse(path.begin(),path.end());
    return 1;
}

int main()
{
    int x,y,z;
    while(scanf("%d%d",&x,&y)!=EOF)
    {
        if(x==0&&y==0)
            break;
        scanf("%d",&z);
        for(int i=0; i<maxn; i++)
            adj[i].clear();
        add(x,y,z);
        while(scanf("%d%d",&x,&y)!=EOF)
        {
            if(y==0&&x==0)
                break;
            scanf("%d",&z);
            add(x,y,z);
        }

        if(solve())
        {
            int i;
            for( i=0; i<path.size()-1; i++)
                printf("%d ",path[i]);
            printf("%d\n",path[i]);
        }
        else
            printf("Round trip does not exist.\n");
    }
    return 0;
}

poj1041 John's trip (无向图求欧拉回路方案)

时间: 2024-10-07 05:43:24

poj1041 John's trip (无向图求欧拉回路方案)的相关文章

poj1041 John&#39;s trip,无向图求欧拉回路路径

点击打开链接 无向图求欧拉回路: 1.图连通 2.所有顶点的度数位偶数 #include <cstdio> #include <cstring> #include <stack> #include <queue> #include <algorithm> using namespace std; const int mt = 2000; const int ms = 50; bool vis[mt+5]; int g[ms][mt+5]; int

POJ 1041 John&#39;s trip 无向图的【欧拉回路】路径输出

欧拉回路第一题TVT 本题的一个小技巧在于: [建立一个存放点与边关系的邻接矩阵] 1.先判断是否存在欧拉路径 无向图: 欧拉回路:连通 + 所有定点的度为偶数 欧拉路径:连通 + 除源点和终点外都为偶数 有向图: 欧拉回路:连通 + 所有点的入度 == 出度 欧拉路径:连通 + 源点 出度-入度=1 && 终点 入度 - 出度 = 1 && 其余点 入度 == 出度: 2.求欧拉路径 : step 1:选取起点(如果是点的度数全为偶数任意点为S如果有两个点的度数位奇数取一

POJ 1041 John&#39;s trip (无向图欧拉回路)

John's trip Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7433   Accepted: 2465   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 frien

UVa10054 The Necklace,无向图求欧拉回路

无向图求欧拉回路: 1.图连通 2.所有顶点的度数位偶数 随便从一个点开始递归遍历即可求出路径 #include <cstdio> #include <cstring> #include <vector> using namespace std; const int maxcolor = 50; int n, G[maxcolor+1][maxcolor+1], deg[maxcolor+1]; struct Edge{ int from, to; Edge(int f

The Necklace UVA - 10054 (无向图的欧拉回路)

The Necklace UVA - 10054 题意:每个珠子有两个颜色,给n个珠子,问能不能连成一个项链,使得项链相邻的珠子颜色相同. 把颜色看做点,珠子内部连一条边,无向图求欧拉回路. 这里我用的并查集. 输出路径就dfs就行了 1 #include <bits/stdc++.h> 2 using namespace std; 3 int g[55][55]; 4 int f[55]; 5 int deg[55]; 6 int n; 7 8 int gf(int x) 9 { 10 re

POJ 1041 John&#39;s trip Euler欧拉回路判定和求回路

就是欧拉判定,判定之后就可以使用DFS求欧拉回路了.图论内容. 这里使用邻接矩阵会快很多速度. 这类题目都是十分困难的,光是定义的记录的数组变量就会是一大堆. #include <cstdio> #include <cstring> #include <stack> #include <vector> using namespace std; struct Edge { int ed, des; Edge(int e = 0, int d = 0) : ed

poj 1041 John&#39;s trip 欧拉回路

题目链接 求给出的图是否存在欧拉回路并输出路径, 从1这个点开始, 输出时按边的升序输出. 将每个点的边排序一下就可以. 1 #include <iostream> 2 #include <vector> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #include <cmath> 7 #include <map> 8 #include

The Necklace UVA 10054 (无向图的欧拉回路,求证Flury算法)

说说:题目的意思本质上就是给你N条无向边,若存在欧拉回路,则将其生成.无向图的欧拉回路的判断非常容易,只要判断是否每个节点都是偶数度即可.但是,对欧拉回路的生成,也就是Fleury算法,貌似有点问题.我自己在这个地方也纠结了好久.下面就来讲讲Fleury算法. 开始我觉得,就是个非常简单的深度优先搜索的问题,直接从任意一个节点,然后不断DFS即可.所以就有了如下的代码: for(i=1;i<MAX;i++) if(map[m][i]>0){ map[m][i]--; map[i][m]--;

UVA 315 Network(无向图求割点)

题目大意 A Telephone Line Company (TLC) is establishing a new telephone cable network. They are connecting several places numbered by integers from 1 to N. No two places have the same number. The lines are bidirectional and always connect together two pl