[lougu1341]无序字母对

Description:

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

Solution:

欧拉回路裸题,注意大写字母和小写字母在ASCII码中不连续,还有要求最小字典序(用multiset存图每次有限遍历最小的)

code:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<set>
using namespace std;
const int MAXX=10000;
multiset<int>to[MAXX];
int f[MAXX],deg[MAXX],q[MAXX];
int n,tot,ans,cnt,s=-1;
bool vis[MAXX],num[MAXX],flag;
inline int find(int x){
	if(f[x]==x)return x;
	else return f[x]=find(f[x]);
}
inline void dfs(int x){
	for(set<int>:: iterator it=to[x].begin();it!=to[x].end();it=to[x].begin()){
		int y=*it;
        to[x].erase(it);
        to[y].erase(to[y].find(x));
        dfs(y);
	}
	q[++tot]=x;
}
int main(){
   cin>>n;
   for(int i=0;i<=99;++i)f[i]=i;
   for(int i=1;i<=n;++i){
   	char a,b;
   	int x,y;
   	cin>>a>>b;
   	x=a-'A';y=b-'A';
   	int u=find(x);
   	int v=find(y);
   	f[u]=v;
   	vis[x]=1;vis[y]=1;
   	deg[x]++;deg[y]++;
   	to[x].insert(y);
   	to[y].insert(x);
   }
   for(int i=0;i<=99;++i){
   	  if(!vis[i])continue;
      num[find(i)]=1;
   }
   for(int i=0;i<=99;++i){
   	if(!vis[i])continue;
   	ans+=num[i];
   	if(s==-1)s=i;
    if(deg[i]&1){
    	cnt++;
    	if(flag)continue;
    	s=i;
    	flag=1;
    }
   }
   if((cnt!=0&&cnt!=2)||ans>1){
   	cout<<"No Solution"<<endl;
   	return 0;
   }
   dfs(s);
   for(int i=tot;i>=1;--i){
   	char ss='A'+q[i];
   	cout<<ss;
   }
   return 0;
}
posted @ 2018-08-28 10:38  ART_coder  阅读(147)  评论(0编辑  收藏  举报