首先图必须是联通的,用并查集判便可c++
无向图欧拉回路:全部点度数都为偶数算法
无向图欧拉路径:两个点(或0个点)度数为奇数,其他点(或全部点)度数为偶数数组
有向图欧拉回路:全部点入度=出度spa
有向图欧拉路径:一个点入度=出度+1,一个点出度=入度+1,其他点(或全部点)入度=出度.net
//已知存在欧拉路径,找该路径 void dfs(int u){//s1~sn中存储的是欧拉路径上的点序列 for(int v=1;v<=n;v++){ if(mp[u][v]>0){ mp[u][v]--; mp[v][u]--; dfs(v); } } s[temp--]=u; }
为何是对的?code
由于找欧拉路径能够经过在图上的两个奇数点之间加一条边转化为求欧拉回路的问题。经过枚举能够发现,存在欧拉回路的图必定是由一些环嵌套而成(能够经过把一些点一分为二近似地当作仙人掌图)递归
将一个环当作主环,要一笔画走完主环,只要在遇到有副环的点u先沿着副环走一圈,再接着沿着主环走就行了ci
Hierholzer算法就是咱们上述思路的一种简单的实现方法:get
咱们将开始dfs的点属于的环视为主环(其实能够有不少种不一样的可能性,不必定就是最显然的那个环),在第一次dfs到没法递归下去时,全部被遍历到的点都在主环上,显然应该将最后遍历到的点放在答案数组的最后,而后一边回溯,若是仍是没法递归,那接着从后往前存入答案数组,若是能够递归说明这个点上有一个副环,沿着副环递归下去,也是一样的最后遍历到的点放在后面,这样子就倒着模拟了咱们以前的算法。it
https://vjudge.net/contest/347059#problem/C
项链的每颗珠子有两面,每面有一种颜色,项链上相邻两颗珠子的相邻面必须是相同的颜色(项链是一个环),给定一些珠子和它们的颜色,问可否用尽全部的珠子来组合成一个项链?
颜色种类=50
将出现的一种颜色视为图上的点,一颗珠子的两个颜色之间有一条边,显然在这样的图上若是存在一条欧拉回路,那么能够组成项链(跑遍全部的边=用尽全部珠子)。
并查集+Hierholzer算法便可。
#include <bits/stdc++.h> using namespace std; const int maxn=1e3+5; int a[maxn],b[maxn]; int mp[55][55]; int du[55]; int s[maxn],tot,temp; void dfs(int u){ for(int v=1;v<=50;v++){ if(mp[u][v]>0){ mp[u][v]--; mp[v][u]--; dfs(v); } } s[temp--]=u; } int fa[55],vis[55]; int find(int x){ return x==fa[x]?x:fa[x]=find(fa[x]); } int main(){ int T; cin>>T; for(int kase=1;kase<=T;kase++){ int n; cin>>n; for(int i=1;i<=50;i++)fa[i]=i; memset(mp,0,sizeof(mp)); memset(du,0,sizeof(du)); memset(s,0,sizeof(s)); memset(vis,0,sizeof(vis)); tot=0; for(int i=1;i<=n;i++){ int u,v; scanf("%d%d",&u,&v); vis[u]=vis[v]=1; int fu=find(u),fv=find(v); fa[fu]=fv; mp[u][v]++; mp[v][u]++; du[u]++; du[v]++; tot++; } int cnt1=0; for(int i=1;i<=50;i++){ if(vis[i]&&fa[i]==i)cnt1++; } if(cnt1>1){ printf("Case #%d\nsome beads may be lost\n",kase); continue; } int flag=1; for(int i=1;i<=50;i++){ if(du[i]&1){ flag=0; break; } } if(!flag){ printf("Case #%d\nsome beads may be lost\n",kase); if(kase<=T)printf("\n"); continue; } temp=tot; for(int i=1;i<=50;i++){//找一个点 if(vis[i]){ dfs(i); break; } } printf("Case #%d\n",kase); for(int i=1;i<=tot;i++){ printf("%d %d\n",s[i],s[i%tot+1]); } if(kase<=T)printf("\n"); } }