并查集判断连通,欧拉回路判断是否成链,看网上很多地方都写得很清楚我就不再说什么是欧拉回路了
注意首尾的判断一定要用入度与出度的差等于1来判断,而不能用认为入度为0,出度为1的时首,入度为1,出度为0的是尾。
给一组数据
1
3
aba
a
ab
Ordering is possible.
#include<iostream>
#define maxn 27+5
using namespace std;
int n;
string cmd;
int f[maxn];
int visit[maxn];
int in[maxn],ou[maxn];
int dfs(int x)
{
if(f[x]!=x) f[x]=dfs(f[x]);
return f[x];
}
void ready()
{
for(int i=0;i<maxn;i++) in[i]=0,ou[i]=0,visit[i]=0,f[i]=i;
}
void build(int x,int y)
{
//cout<<x<<" "<<y<<endl;
if(dfs(x)!=dfs(y)&&x!=y) f[dfs(x)]=dfs(y);
visit[x]=visit[y]=1;
ou[x]++;in[y]++;
}
int main()
{
int t;
cin>>t;
while(t--)
{
ready();
cin>>n;
while(n--)
{
cin>>cmd;
build(cmd[0]-'a',cmd[cmd.size()-1]-'a');
}
int cent=0;
int sum=0;//总数;
int m=0,nn=0,d=0;//m,入度出度均为的点,n入度为0出度为1,d入度为0,出度为1,
for(int i=0;i<maxn;i++)
{
if(visit[i]) sum++;
if(visit[i]&&f[i]==i) cent++;
if(visit[i]&&in[i]==ou[i]) m++;
if(visit[i]&&in[i]-ou[i]==1) nn++;
if(visit[i]&&in[i]-ou[i]==1) d++;
}
//cout<<cent<<endl;
//cout<<sum<<" "<<m<<" "<<nn<<" "<<d<<endl;
if(cent==1)
{
if(m==sum||((m==sum-2)&&nn==1&&d==1)) cout<<"Ordering is possible."<<endl;
else cout<<"The door cannot be opened."<<endl;
}
else
{
cout<<"The door cannot be opened."<<endl;
}
}
return 0;
}