【欧拉回路】Play On Words(6-16)

[UVA10129]Play On Words

算法入门经典第6章6-16(P169)

题目大意:有一些单词,问能不能将它们串成字符串(只有前缀和后缀相同才能连)

试题分析:很巧妙的一道题,将每个单词的首尾字符相连,先判断出现过的单词的连通性(并查集),再利用欧拉路有向图的判定方法判定是否构成欧拉路。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;

inline int read(){
	int x=0,f=1;char c=getchar();
	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
	for(;isdigit(c);c=getchar()) x=x*10+c-'0';
	return x*f;
}
const int MAXN=100001;
const int INF=999999;
int N,M;
int T;
int fa[27];
int Hash[27];
int root;

int find(int x){
	if(x!=fa[x]) return fa[x]=find(fa[x]);
	return x;
}
void merge(int a,int b){
	int x=find(a);
	int y=find(b);
	if(x==y) return ;
	fa[y]=x;
	root=x;
}
char str[1001];
int od[27],id[27];

int main(){
	T=read();
	while(T--){
		N=read(); bool flag=false;
		memset(od,0,sizeof(od));
		memset(id,0,sizeof(id));
		memset(Hash,false,sizeof(Hash));
		for(int i=0;i<=26;i++) fa[i]=i;
		for(int i=1;i<=N;i++){
			scanf("%s",str);
			int len=strlen(str);
			merge(str[0]-'a',str[len-1]-'a');
			od[str[0]-'a']++;
			id[str[len-1]-'a']++;
			Hash[str[len-1]-'a']=Hash[str[0]-'a']=true;
		}
		for(int i=0;i<26;i++){
			if(Hash[i]&&find(i)!=root) {printf("The door cannot be opened.\n");flag=true;break;}
		}
		if(flag) continue;
		int a=0,b=0;
		for(int i=0;i<26;i++){
			if(abs(od[i]-id[i])>1){
				printf("The door cannot be opened.\n");
				flag=true; break;
			}
			else{
				if(od[i]-id[i]==1) a++;
				else if(id[i]-od[i]==1) b++;
			}
		}
		if(flag) continue;
		if((!a&&!b)||(a==1&&b==1)){
			printf("Ordering is possible.\n");
		}
		else{
			printf("The door cannot be opened.\n");
		}
	}
}

 

posted @ 2017-08-06 21:51  wxjor  阅读(192)  评论(0编辑  收藏  举报