uva10054 - The Necklace

博客围绕无向图欧拉回路展开,介绍了其存在性判定条件为图联通且各点度为偶数,还说明了构造方法是从任一点出发按“能走就走”原则访问边。结合具体题目,指出珠子是边、颜色是点,建好图后跑欧拉回路即可,并给出题目链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接

https://vjudge.net/problem/UVA-10054

无向图欧拉回路

存在性判定:图是联通的,而且每个点的度都是偶数(充要条件)
欧拉回路的构造:
从任意一个点出发dfs,以"能走就走"的原则访问每条边;
注意要先把所有的出边都走完了才能输出自己,这里的逻辑和欧拉路径中是一样的,下面的图片可以解释这个问题
在这里插入图片描述
红色是起点,如果我在“十字路口”处先走了大圆上的点,那么按照"先输出再遍历"就会得到错误的答案
这里的问题和欧拉路径中的问题是一样的,可以这样理解,只要我按照这种方式进展,那么最后那个"死胡同"上的点一定会最先进栈,而在我还没访问“死胡同”之前,当前点肯定不会进栈(它也不应该此时进栈),只有我访问完"死胡同"之后,这个点才会进栈。

题解

这题是无向图的欧拉回路,欧拉回路是每条边都走一此,所以珠子是边,颜色是点
建好图之后跑欧拉回路就行了

代码

#include <bits/stdc++.h>
#define maxn 2019
#define maxe 2019
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
struct Graph
{
    int etot, head[maxn], to[maxe], next[maxe], w[maxe];
    void clear(int v)
    {
        int i;
        for(i=1;i<=v;i++)head[i]=0;
        for(i=1;i<=etot;i++)to[i]=next[i]=w[i]=0;
        etot=1;
    }
    void adde(int a, int b, int c){to[++etot]=b;w[etot]=c;next[etot]=head[a];head[a]=etot;}
}G;
struct Euler_Circuit
{
    bool vis[maxe];
    int vlis[maxe];
    void clear(int e){for(auto i=1;i<=e;i++)vis[i]=false;*vlis=0;}
    void dfs(Graph &G, int pos)
    {
        for(auto p=G.head[pos];p;p=G.next[p])if(!vis[p])vis[p]=vis[p^1]=true, dfs(G,G.to[p]);
        vlis[++*vlis]=pos;
    }
}euler;
int deg[60], N;
int main()
{
    int i, u, v, kase(0), T;
    ios::sync_with_stdio(false);
    cin>>T;
    while(T--)
    {
        euler.clear(G.etot);
        G.clear(50);
        cl(deg);
        cin>>N;
        for(i=1;i<=N;i++)cin>>u>>v, G.adde(u,v,0), G.adde(v,u,0), deg[u]++, deg[v]++;
        if(kase)cout<<endl;
        cout<<"Case #"<<++kase<<endl;
        for(i=1;i<=50;i++)if(deg[i]&1)break;
        if(i<=50){cout<<"some beads may be lost"<<endl;continue;}
        for(i=1;i<=50;i++)if(deg[i])break;
        euler.dfs(G,i);
        if(*euler.vlis<N+1){cout<<"some beads may be lost"<<endl;continue;}
        for(i=1;i<*euler.vlis;i++)cout<<euler.vlis[i]<<' '<<euler.vlis[i+1]<<endl;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值