欧拉回路 在加上 并查集判断连通性,把每一个单词当做一个边,话说我一开始当做h路做的。。。。。
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
int father[26],rank[26],r[26],c[26],mark[26];
int find(int x)
{ //cout<<11111<<endl;
if(father[x]==x)
return x;
else
return father[x]=find(father[x]);
}
void uion(int m,int n)
{
int x=find(m);
int y=find(n);
if(rank[x]==rank[y])
{
rank[x]++;
father[y]=x;
}
else if(rank[x]>rank[y])
{
father[y]=x;
}
else
{
father[x]=y;
}
}
int main()
{
int total_case,iii;
scanf("%d",&total_case);
for(iii=0;iii<total_case;iii++)
{
int i,n,mm=0;
memset(mark,0,sizeof(mark));
memset(rank,0,sizeof(rank));
memset(r,0,sizeof(r));
memset(c,0,sizeof(c));
for(i=0;i<26;i++)
father[i]=i;
scanf("%d",&n);
//cout<<mark[i]<<endl;
for(i=0;i<n;i++)
{
string s;
cin>>s;
int m=s[0]-'a',n=s[s.length()-1]-'a';
mark[n]=1;
mark[m]=1;
uion(m,n);
r[n]++;
c[m]++;
}
//cout<<mark[1]<<endl;
int k=-1;
for(i=0;i<26;i++)
{
if(mark[i]==1)
{
if(k==-1)
k=find(father[i]);
else
{
if(k==find(father[i]))
continue;
else
mm=1;
break;
}
}
}
//cout<<mark[1]<<endl;
//cout<<mark[1]<<endl;
if(mm==0)
{
int ru=0,chu=0;
for(i=0;i<26;i++)
{
if(r[i]==c[i])
{
}
else if(ru==0&&r[i]-c[i]==1)
ru++;
else if(chu==0&&c[i]-r[i]==1)
chu++;
else
{
mm=1;
break;
}
}
if((ru==1&&chu==1)||(ru==0&&chu==0))
{}
else
mm=1;
}
if(mm==0)
printf("Ordering is possible.\n");
else
printf("The door cannot be opened.\n");
}
}