首页 > 其他 > 详细

UOJ #117.欧拉回路

时间:2020-11-29 10:27:47      阅读:24      评论:0      收藏:0      [点我收藏+]

Description

有一天一位灵魂画师画了一张图,现在要你找出欧拉回路,即在图中找一个环使得每条边都在环上出现恰好一次。

一共两个子任务:

  1. 这张图是无向图。(50分)
  2. 这张图是有向图。(50分)

Solution

有向图中出度等于入度,无向图中度数为偶数就有欧拉回路

需要特判图是否联通

还需要动态地更新head以保证不去查询已经走过的边

技术分享图片
#include<iostream>
#include<cstdio>
using namespace std;
int t,n,m,fa[100005],head[100005],tot=1,id[100005],od[100005],sta[100005],top,s;
bool vst[200005];
struct Edge
{
    int to,nxt,w;
}edge[400005];
inline int read()
{
    int f=1,w=0;
    char ch=0;
    while(ch<0||ch>9){if(ch==-) f=-1;ch=getchar();}
    while(ch>=0&&ch<=9) w=(w<<1)+(w<<3)+ch-0,ch=getchar();
    return f*w;
}
int find(int x)
{
    return (fa[x]==x)?fa[x]:fa[x]=find(fa[x]);
}
void dfs(int k)
{
    for(int i=head[k];i;)
        if(vst[i>>1]) head[k]=edge[i].nxt,i=edge[i].nxt;
        else vst[i>>1]=true,dfs(edge[i].to),sta[++top]=edge[i].w,i=head[k];
}
int main()
{
    t=read(),n=read(),m=read();
    for(int i=1;i<=n;i++) fa[i]=i;
    for(int i=1;i<=m;i++)
    {
        int u=read(),v=read();
        fa[find(u)]=find(v);
        if(t==1) edge[++tot]=(Edge){v,head[u],i},head[u]=tot,edge[++tot]=(Edge){u,head[v],-i},head[v]=tot,id[u]++,id[v]++;
        else edge[++tot]=(Edge){v,head[u],i},head[u]=tot,++tot,id[v]++,od[u]++;
    }
    if(t==1) for(int i=1;i<=n;i++) if(id[i]&1) return puts("NO"),0;else;
    else for(int i=1;i<=n;i++) if(id[i]!=od[i]) return puts("NO"),0;
    for(int i=1;i<=n;i++) if(id[i]) s=i;
    for(int i=1;i<=n;i++) if(id[i]&&find(i)!=find(s)) return puts("NO"),0;
    dfs(s),puts("YES");
    for(int i=top;i;i--) printf("%d ",sta[i]);
    return 0;
}
欧拉回路

 

UOJ #117.欧拉回路

原文:https://www.cnblogs.com/JDFZ-ZZ/p/14055399.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!