POJ 1041 - John's trip(欧拉回路)

题目:

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=90847#problem/A

题意:

求无向图的欧拉回路是否存在,若存在则输出字典序最小的路径。

思路:

先判断是否存在欧拉回路。

对于无向图,所有的数的度都为偶数则存在。

dfs 枚举边,得到答案。

AC.

#include <iostream>
#include <cstdio>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>

using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 50;
const int maxm = 2000;

int n, m;
int du[maxn];

struct Edge{
    int u, v;
}edge[maxm];
void addedge(int u, int v, int id)
{
    edge[id].u = u;
    edge[id].v = v;
}

int vis[maxm];
int path[maxm], tol;
void dfs(int u)
{
    int v;
    for(int i = 1; i <= m; ++i) {
        if(vis[i]) continue;
        if(edge[i].u == u) {
            v = edge[i].v;
            vis[i] = 1;
            dfs(v);
            path[tol++] = i;
        }
        else if(edge[i].v == u) {
            v = edge[i].u;
            vis[i] = 1;
            dfs(v);
            path[tol++] = i;
        }
    }
}
void init()
{
    tol = 0;
    memset(du, 0, sizeof(du));
    memset(vis, 0, sizeof(vis));
}
int main()
{
    //freopen("in", "r", stdin);
    int u, v, id;
    while(~scanf("%d%d", &u, &v)) {
        if(u == 0 && v == 0) break;

        init();
        n = 0; m = 0;
        int s;

        scanf("%d", &id);
        addedge(u, v, id);
        n = max(n, max(u, v));
        m = max(m, id);
        if(id == 1) {
            s = min(u, v);
        }
        du[u]++; du[v]++;

        while(1) {
            scanf("%d%d", &u, &v);
            if(u+v == 0) break;
            scanf("%d", &id);

            n = max(n, max(u, v));
            m = max(m, id);
            if(id == 1) {
                s = min(u, v);
            }
            addedge(u, v, id);
            du[u]++; du[v]++;
        }

        bool flag = 1;
        for(int i = 1; i <= n; ++i) {
            if(du[i]%2) {
                flag = 0;
                break;
            }
        }

        if(!flag) printf("Round trip does not exist.\n");
        else {
            dfs(s);
            for(int i = tol-1; i >= 0; --i) {
                printf("%d", path[i]);
                if(i == 0) printf("\n");
                else printf(" ");
            }
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值