无序字母对:输出欧拉路径

题目描述

给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现。

题解

显然我们要找一条欧拉路径或者欧拉回路,这里学习一种新算法,借用DFS栈输出答案,我们发现当我们一直DFS下去的时候可能有一些边最后没能走到,就会在回来的时候又被递归下去,我们发现这刚好是我们想要的,就是走到分界点的时候走回来又走出去所以只要在DFS只后把答案放进去即可,输出要倒序

代码

#include <bits/stdc++.h>
#define maxn 10005
#define LL long long
#define INF 0x3f3f3f3f
#define I inline
#define re register
using namespace std;
int read(){
	int res; bool f=1; char c;
	while(!isdigit(c=getchar())) if(c=='-') f=0; res=c^48;
	while(isdigit(c=getchar())) res=(res<<3)+(res<<1)+(c^48);
	return f?res:-res;
}
struct NODE{
	int x,id;
	bool operator < (const NODE &rhs)const{return x<rhs.x;}
};
vector<NODE> E[maxn];
vector<int> ans;
int n,s,cnt,du[maxn];
bool vis[maxn];
void DFS(int u){
	for(int i=0;i<E[u].size();i++){
		int v=E[u][i].x; if(vis[E[u][i].id]) continue;
		vis[E[u][i].id]=1; DFS(v);
	}
	ans.push_back(u);
}
int main(){
	n=read();
	for(int i=1;i<=n;i++){
		char c[3],x,y; scanf("%s",c+1); x=c[1]-'A'; y=c[2]-'A';
		du[x]++; du[y]++;
		E[x].push_back((NODE){y,i});
		E[y].push_back((NODE){x,i});
		vis[x]=1; vis[y]=1;
	}
	for(int i=0;i<100;i++) sort(E[i].begin(),E[i].end());
	for(int i=0;i<100;i++){
		if(vis[i] && du[i]&1) cnt++;
	}
	if(!(cnt==0||cnt==2)) {puts("No Solution"); return 0;}
	if(cnt==0){
		for(int i=0;i<100;i++){
			if(vis[i]) {s=i; break;}
		}
	}
	else{
		for(int i=0;i<100;i++){
			if(du[i]&1) {s=i; break;}
		}
	}
	memset(vis,0,sizeof vis);
	DFS(s);
	if(ans.size()<n+1){puts("No Solution");}
	else{for(int i=ans.size()-1;~i;i--) printf("%c",ans[i]+'A');}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jarden_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值