本来以为这个题就是简单的并查集,但如果只用并查集的话就没办法解决重复输入的问题,于是百度,发现了这个:欧拉路!!!
安利一个博客:http://blog.csdn.net/niushuai666/article/details/6917777
所以这个题简单说就是定义一个in和out的数组,把每个单词的头和尾出现次数分别放在in和out中,最后进行判断。
#include<iostream>
#include <cstdio>
#include<string>
#include <memory.h>
using namespace std;
int in[30],out[30],pre[30];
bool visited[30];
int findpre(int x)
{
if(x==pre[x])
return x;
return findpre(pre[x]);
}
int main()
{
int test, i, n;
string s;
scanf("%d", &test);
while(test--)
{
scanf("%d", &n);
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
memset(visited,false,sizeof(visited));
for(i=0; i<30; i++)
pre[i] = i;
int x,y;
for(i=0; i<n; i++)
{
cin >> s;
x=s[0]-'a';
y=s[s.length()-1]-'a';
out[x]++;
in[y]++;
pre[x]=pre[y]=findpre(x);
visited[x]=visited[y]=true;
}
int r=0;
for(i=0; i<30; i++)
{
if(visited[i] && i==pre[i])
{
r++;
}
}
int z;
x=0; y=0; z=0;
for(i=0; i<30; i++)
{
if(visited[i] && in[i]!=out[i])
{
if(in[i] == out[i]+1)
{
x++;
}
else if(in[i]+1 == out[i])
{
y++;
}
else z++;
}
}
if(((x==1 && y==1) || (x==0 && y==0)) && !z && r < 2)
{
cout<<"Ordering is possible."<<endl;
continue;
}
else
{
cout<<"The door cannot be opened."<<endl;
}
}
return 0;
}