题目链接:
#include<iostream>
#include<cstdio>
#include<cstring>
#define M 28
using namespace std;
int fa[M];
int Find(int x)
{
return x==fa[x]?x:fa[x]=Find(fa[x]);
}
int main()
{
int T,n;
char str[1005];
int in_degree[M],out_degree[M];
int vis[M];
int a,b;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0; i<26; i++){
vis[i]=in_degree[i]=out_degree[i]=0;
fa[i]=i;
}
while(n--)
{
scanf("%s",str);
a=str[0]-'a';
b=str[strlen(str)-1]-'a';
out_degree[a]++;
in_degree[b]++;
fa[Find(a)]=Find(b);
vis[a]=vis[b]=1;
}
int connect=1,flag=0;
for(int i=0;i<26;i++){
if(vis[i]&&!flag)
{
flag=1;
a=Find(i);
}
else if(vis[i])
{
b=Find(i);
if(a!=b)
connect=0;
}
}
int start=0,endd=0,node=0,d;
flag=0;
for(int i=0; i<26; i++)
{
d=in_degree[i]-out_degree[i];
if(d==0)
node++;
else if(d==1)
endd++;
else if(d==-1)
start++;
else
flag=1;
}
if(!connect)
cout<<"The door cannot be opened."<<endl;
else if(flag)
cout<<"The door cannot be opened."<<endl;
else if(start==1&&endd==1||start==0&&endd==0)
cout<<"Ordering is possible."<<endl;
else
cout<<"The door cannot be opened."<<endl;
}
return 0;
}
题意:
有些秘门带有一个有趣的词迷。考古学家必须解开词迷才能打开门。由于没有其他方法可以
打开门,因此词迷就变得很重要。每个门上有许多磁盘。每个盘上有一个单词,这些磁盘必须重新排列使得每个单词第一个字
母跟前一个单词最后一个字母相同。例如单词"acm"可以跟在单词"motorola"的后面。你的任务是
编写一个程序,读入一组单词,然后判定是否可以经过重组使得每个单词第一个字母跟前一个单
词最后一个字母相同,这样才能打开门。
思路:
1:用并查集判断图的连通性
2:单向图中,当满足图连通时,图中存在一个 入度-出度=1的顶点,一个出度-入度=1的顶点, 其他顶点入度=出度 那么这个图是欧拉通路
当满足图连通时, 所有顶点入度=出度 那么这个图是欧拉回路
代码: