Play on Words UVA - 10129 (欧拉路径)
Play on Words
题意:给出一些单词,问能否让首尾字母相同的字符串相连,最后形成一个串。
思路:不难看出,这是一个欧拉道路问题。
简单介绍一下欧拉道路:
在欧拉道路中,除了起点和终点,所有的点的入度和出度都相等。(如所有的点的入度都等于出度,那么就形成欧拉回路)并且整幅图是联通的,那么这就形成了欧拉回路、道路。
是否联通,我们通常通过并查集判断。
AC代码:
#include<cstdio>
#include<iostream>
#include<map>
#include<vector>
#include<cstring>
using namespace std;
int ind[30];
int outd[30];
int fa[30];
void init()
{
for(int i=0;i<26;i++)
{
fa[i]=i;
}
}
int find(int x)
{
return x==fa[x]?x:fa[x]=find(fa[x]);
}
void merge(int x,int y)
{
int fx=find(x);
int fy=find(y);
fa[fy]=fx;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(ind,0,sizeof(ind));
memset(outd,0,sizeof(outd));
int n;
scanf("%d",&n);
init();
for(int i=0;i<n;i++)
{
char s[1005];
scanf("%s",s);
int u=s[0]-'a';
int v=s[strlen(s)-1]-'a';
ind[v]++,outd[u]++;
merge(u,v);
}
vector<int> ans;
int flag=1;
int cnt=0;
for(int i=0;i<26;i++)
{
if(ind[i]!=outd[i])
{
ans.push_back(i);
}
if(ans.size()>2) {flag=0;break;}
if((ind[i]||outd[i])&&fa[i]==i){cnt++;}
if(cnt>1){flag=0;break;}
}
if(ans.size()==2)
{
int a=ans[0],b=ans[1];
if(ind[a]+ind[b]==outd[a]+outd[b]&&(outd[a]-ind[a]==1||outd[a]-ind[a]==-1))
{
flag=1;
}
else flag=0;
}
if(!flag) cout<<"The door cannot be opened."<<endl;
else cout<<"Ordering is possible."<<endl;
}
}