链接
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;
}
}