无向图中欧拉回路的求法 poj1041

Poj 1041 John’s trip
就是无向图中欧拉回路的求法
首先判断是否存在欧拉回路 判断图的连通性利用并查集实现 然互判断每个点的度数是否为偶数 如果判断存在欧拉回路则利用dfs打印出欧拉回路

#include <iostream>
#include <algorithm>
#include <vector>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
const int nmax=100;
const int mmax=2000;
int fa[nmax];//并查集
int vis[mmax];//边的访问数组
vector <pair<int,int>> g[nmax];//连接表
int du[nmax];
int q[nmax];
int top;
void init()
{
    for(int i=0;i<nmax;i++)//初始化并查集 清空链接表 清空度
    {
        fa[i]=i;
        g[i].clear();
        du[i]=0;
    }
    memset(vis,0,sizeof(vis));//初始化边的访问数组
    top=0;

}
int findfa(int x){if(fa[x]==x)return x;else return fa[x]=findfa(fa[x]);}//并查集搜索函数
void merge(int a,int b)//检查a和b是否属于同一个并查集  不属于的话合并他们
{
    int x,y;
    x=findfa(a);
    y=findfa(b);
    if(x!=y)
        fa[a]=b;
}
bool judge()//判断是否含有欧拉回路
{
    int root=findfa(1);
    for(int i=1;i<nmax;i++)//检查图的连同性和每个节点的度是否为偶数
    {
        if(du[i]&&(root!=findfa(i)))
            return false;
        if(du[i]&&(du[i]&1))
            return false;
    }
    return true;

}
bool cmp(pair<int ,int> a,pair<int ,int > b)
{
    return a.second<b.second;
}
void mysort()
{
    for(int i=1;i<nmax;i++)
    {
        if(du[i])
        {
            sort(g[i].begin(),g[i].end(),cmp);
        }
    }
}
void dfs(int s)
{
    for(int i=0;i<g[s].size();i++)
    {
        if(!vis[g[s][i].second])
        {
            vis[g[s][i].second]=1;
            q[top++]=g[s][i].second;//存储边   
            dfs(g[s][i].first);
        }

    }
}
void output()
{
    for(int i=0;i<top;i++)
    {
        if(i!=top-1)printf("%d ",q[i]);
        else printf("%d\n",q[i]);
    }
}
int main(int argc,char *argv[])
{
    int a,b,z,start;

    while(scanf("%d %d",&a,&b)!=EOF)
    {
        init();//初始化并查集 边访问数组 清空度 连接表
        if(a==0&&b==0)break;
        scanf("%d",&z);
        start=min(a,b);
        g[a].push_back(make_pair(b,z));
        g[b].push_back(make_pair(a,z));
        du[a]++;
        du[b]++;
        merge(a,b);//ab合并成同一个并查集
        while(scanf("%d %d",&a,&b)!=EOF)
        {
            if(a==0&&b==0)break;
            scanf("%d",&z);
            g[a].push_back(make_pair(b,z));
            g[b].push_back(make_pair(a,z));
            du[a]++;
            du[b]++;
            merge(a,b);
        }
        if(judge())
        {
            mysort();
            dfs(start);
            output();
        }
        else 
            printf("Round trip does not exist.\n");
    }
    return 0;
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

hebastast

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

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

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

打赏作者

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

抵扣说明:

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

余额充值