找欧拉回路为什么要回溯的时候存?

题目
由题可知,优先选字典序小的字符
例如:

此时有两个奇点 ab
优先选 a
若正序保存
则序列为

a,b,c,d

显然这不是正解
则回溯的时候存

则序列为

b,d,c,a

reverse 一下

a,c,d,b

正确✔
为何?
因为:

#include<bits/stdc++.h>
using namespace std;
int n,head;
char a[2];
int b[130][130];//存图
int deg[130],fa[130];//deg存储度数,fa存储父亲,用来并查集判断是否联通
char ans[1330];//稍大于51*52/2
int find(int x) {
if(fa[x]==x)return x;
return fa[x]=find(fa[x]);
}
void dfs(int x) { //找欧拉回路/路径
for(int i=64; i<=125; i++)
if(b[x][i]) {
b[x][i]=b[i][x]=0;
dfs(i);
}
ans[n--]=x;//因为是回溯的时候存,所以倒着存!!!!!!!
}
int main() {
cin>>n;
for(int i=64; i<=125; i++)fa[i]=i;
//A在ASCII码表里为65,z为122,所以64~125就足够了
for(int i=1; i<=n; i++) {
cin>>a;
b[a[0]][a[1]]=b[a[1]][a[0]]=1;
deg[a[0]]++;
deg[a[1]]++;
int xx=find(a[0]),yy=find(a[1]);
fa[xx]=yy;
}
int cnt=0;
for(int i=64; i<=125; i++)
if(fa[i]==i&&deg[i])cnt++;//祖宗结点
if(cnt!=1) {
cout<<"No Solution"<<endl; //如果不是连通图
return 0;
}
cnt=0;
head=0;
for(int i=64; i<=125; i++) {
if(deg[i]&1) {
cnt++;
if(head==0)head=i;//顺道存储起点
}
}
if(cnt&&cnt!=2) {
cout<<"No Solution"<<endl;
return 0;
}
//如果有奇数度数的点,并且不是两个,说明不存在欧拉回路/路径
if(head==0)//如果是欧拉回路
for(int i=64; i<=125; i++)
if(deg[i]) {
head=i; //找欧拉回路的起点
break;
}
dfs(head);
cout<<ans;
return 0;
}
posted @   ShaoJia  阅读(91)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示