随便看hdu 看到的 就做了一下 前两天刚做过类似的 就是并查集看图是不是连通 然后判断是否可以构成欧拉通路
并查集没啥讲的了。 还有用一个exist数组 记录 图中是否有这个点
这次的欧拉通路是有向图 不用开两个数组 直接用degree记录 出度减去入度的值 所以每次输入一个单词 其实就是输入一条从首字符指向最后一个字符的边 首字符的degree++
最后一个字符的 degree-- 最后首先统计并查集 fa==-1 并且exist==1 的个数 超过1 了就不连通
然后看degree 全0可以 直接是欧拉回路
如果有两个不是0 记录下来 只要一个是1 另一个是-1 就可以了
1A的
别的没啥了。。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=27;
int fa[maxn];
bool exist[maxn];
int degree[maxn];
int findset(int a)
{
while(fa[a]!=-1)
a=fa[a];
return a;
}
void Union(int a,int b)
{
int x1=findset(a);
int x2=findset(b);
if(x1!=x2)
fa[x2]=x1;
}
int main()
{
int T;scanf("%d",&T);
int n,i,j,f,t;
char str[1005];
while(T--)
{
memset(exist,0,sizeof(exist));
memset(degree,0,sizeof(degree));
memset(fa,-1,sizeof(fa));
scanf("%d",&n);
for(i=0;i<n;++i)
{
scanf("%s",str);
f=str[0]-'a';
t=str[strlen(str)-1]-'a';
exist[f]=exist[t]=1;
degree[f]++;
degree[t]--;
Union(f,t);
}
int cnt1=0,cnt2=0;
bool flag=0;
int index1=0,index2;
for(i=0;i<26;++i)
{
if(exist[i]==1 && fa[i]==-1)
cnt1++;
if(degree[i]!=0)
{
cnt2++;
if(index1==0)
index1=degree[i];
else
index2=degree[i];
}
}
if(cnt1!=1 || cnt2>2 || cnt2==1)
printf("The door cannot be opened.\n");
else if(cnt2==0)
printf("Ordering is possible.\n");
else
{
if((index1==1 && index2==-1) || (index1==-1 && index2==1))
printf("Ordering is possible.\n");
else
printf("The door cannot be opened.\n");
}
}
return 0;
}