输入 n(n<=100000)个单词,是否可以把所有这些单词排成一个序列,使得每个单词的第一个字母和上一个单词的最后一个字母相同(例如 acm\malform\mouse).每个单词最多包括1000个小写字母。输入中可以有重复单词。
1、图是连通得 ;
2、最多存在两个结点 进的次数和出的次数不相等,且一个为头 一个为尾;
本题我才用的是dfs法;
#include <iostream>
#include <cstring>
using namespace std;
int n;int frist,last;//每个单词的首字母和尾字母
int aa[26][26];int begin;//欧拉道路的头;
int inaa[260],outaa[260],vis[260];//进结点的次数,出结点的次数,以及标记有哪些结点;
bool is_ok()//判断是否满足欧拉道路的条件
{
bool markstart=true,markend=true;
for(int i=0;i<26;i++)
{
if(vis[i]&&inaa[i]!=outaa[i])
{
if(markstart&&inaa[i]==outaa[i]-1)
{
markstart=!markstart;begin=i;
}
else if(markend&&inaa[i]==outaa[i]+1)
{
markend=!markend;
}
else
{
return false;
}
}
}
return true;
}
void dfs(int i)
{
for(int j=0;j<26;j++)
if(aa[i][j]==1)
{
aa[i][j]++;
dfs(j);
}
}
bool ok_dfs()
{
for(int i=0;i<26;i++)
for(int j=0;j<26;j++)
if(aa[i][j]==1)
return false;
return true;
}
int main()
{
int k;
cin>>k;
while(k--)
{memset(vis,0,260);
memset(inaa,0,260);
memset(outaa,0,260);
memset(aa,0,sizeof(aa));
cin>>n;
for(int i=0;i<n;i++)
{
string h;
cin>>h;
frist=h[0]-'a';
last=h[h.length()-1]-'a';
aa[frist][last]=1;
vis[frist]++;
vis[last]++;
outaa[frist]++;
inaa[last]++;begin=frist;
}
if(is_ok())
{
dfs(begin);
if(ok_dfs())
cout<<"Ordering is possible."<<endl;
else
cout<<"The door cannot be opened."<<endl;
}
else
cout<<"The door cannot be opened."<<endl;
}
}