题意:给你n个单词,每个单词可以和另一个单词连接,前提是(这个单词的尾字母等下一个单词的首字母),问你有没有一种连法能够连接所有的单词;
解题思路:每个单词可以看成是首字母指向尾字母的一条边,那么就变成求欧拉通路的问题了;
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int f[];
int findf(int u)
{
if(f[u]==u)
return u;
else
{
f[u]=findf(f[u]);
return f[u];
}
}
void join(int x,int y)
{
int t1=findf(x);
int t2=findf(y);
f[t2]=t1;
}
int main()
{
int tt;
int n;
int flag;
int cnt1,cnt2;
int father;
int indeg[];
int outdeg[];
char t[];
scanf("%d",&tt);
while(tt--)
{
memset(outdeg,,sizeof(outdeg));
memset(indeg,,sizeof(indeg));
for(int i=;i<;i++)
f[i]=i;
flag=cnt1=cnt2=;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%s",t);
int len=strlen(t);
int x=t[]-'a'+;
int y=t[len-]-'a'+;
outdeg[x]++;
indeg[y]++;
join(x,y);
father=y;
}
for(int i=;i<=;i++)
{
if(outdeg[i]!=||indeg[i]!=)
{
if(findf(i)!=findf(father))
flag=;
}
}
if(flag)
{
printf("The door cannot be opened.\n");continue;
}
for(int i=;i<=;i++)
{
if(indeg[i]!=outdeg[i])
{
if(indeg[i]-outdeg[i]==)
cnt1++;
else if(indeg[i]-outdeg[i]==-)
cnt2++;
else
{
flag=;break;
}
}
}
if(cnt1!=cnt2)
{
flag=;
}
else
{
if(cnt1>)
flag=;
}
if(flag)
printf("The door cannot be opened.\n");
else
printf("Ordering is possible.\n");
}
}