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;

}

 

你可能感兴趣的:(poj)