洛谷 [P1341]无序字母对

这道题第一眼以为是一道字符串的题,但细想一下是一道求欧拉路的图论题。

把每一对对应关系看成一条边,本题即求这张图上是否存在一个欧拉回路或欧拉路,并要求字典序最小的方案,那么我们在dfs的时候就要从该点所连的最小的点开始遍历,并将所得的结果存在一个数组中,最后逆序输出。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cmath>
using namespace std;
int read(){
	int rv=0,fh=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-') fh=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		rv=(rv<<1)+(rv<<3)+c-'0';
		c=getchar();
	}
	return rv*fh;
}
int bian[150][150],n,cnt[150],mi,cn;
int zc[10005];
bool f=0;
void dfs(int u,int k){
	//printf("%c",u+'A'-1);
	for(int i=1;i<=150;i++){
		if(bian[u][i]){
			bian[i][u]=bian[u][i]=0;
			dfs(i,k+1);
		}
	}
	zc[++zc[0]]=u+'A'-1;
}
int main(){
	freopen("in.txt","r",stdin);
	n=read();
	for(int i=1;i<=n;i++){
		char a,b;
		scanf(" %c %c ",&a,&b);
		a-='A'-1;
		b-='A'-1;
		//cout<<(int)a<<" "<<(int)b<<endl;
		bian[a][b]=bian[b][a]=1;
		cnt[a]++;cnt[b]++;
	}
	for(int i=149;i>=1;i--){
		if(cnt[i]){
			if(cnt[i]&1) {cn++;mi=i;}
		}
	}
	if(cn>=3||cn==1){
		//cout<<cn<<endl;
		printf("No Solution");
		return 0;
	}
	if(!mi){
		for(int i=1;i<=149;i++){
			if(cnt[i]) {mi=i;break;}
		}
	}
	//cout<<mi<<endl;
	dfs(mi,1);
	//printf("%d
",zc[0]);
		for(int i=zc[0];i>=1;i--) printf("%c",zc[i]);
	fclose(stdin);
	return 0;
}
原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/7868321.html