题目大意:给出n个单词,每个单词的尾字母可以和其他单词的头字母相连,问是否所有单词可以连接成一条线(包括形成环),但不能分叉
解题思路:首先用并查集求出根的数目,再用每个字母入度和出度的情况来判断是否为全部连接成一条线
#include <bits/stdc++.h>
using namespace std;
char s[1100];
int in[30],out[30],exist[30],par[30];
int Find(int x)
{
if(x != par[x])
par[x] = Find(par[x]);
return par[x];
}
void Union(int x,int y)
{
int px = Find(x);
int py = Find(y);
if(px != py)
par[px] = py;
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
memset(exist,0,sizeof(exist));
for(int i = 0; i < 26; i++)
par[i] = i;
scanf("%d",&n);
for(int i = 0; i < n; i++)
{
scanf("%s",s);
int x = s[0]-'a';
int y = s[strlen(s)-1]-'a';
in[x]++;
out[y]++;
exist[x] = 1;
exist[y] = 1;
Union(x,y);
}
int root = 0;
for(int i = 0; i < 26; i++)
if(exist[i] && par[i]==i)
root++;
if(root > 1)
{
puts("The door cannot be opened.");
continue;
}
int s1=0,s2=0;
int i;
for(i = 0; i < 26; i++)
{
if(exist[i] && in[i] != out[i])
{
if(in[i]-out[i]==1)
s1++;
else if(out[i]-in[i]==1)
s2++;
else
break;
}
}
if(i<26)
puts("The door cannot be opened.");
else if(s1+s2==0 || (s1==1&&s2==1))
puts("Ordering is possible.");
else
puts("The door cannot be opened.");
}
return 0;
}