标签:
链接:点击打开链接
题意:给出一些单词看能否首位相接
代码:
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
using namespace std;
int fa[1005],in[1005],out[1005],vis[1005],temp[1005];
char s[1005];
int found(int x){ //找根节点
if(x!=fa[x])
fa[x]=found(fa[x]);
return fa[x];
}
int main(){ //有向连通图D含有欧拉通路,当且仅当该图为连通图且D中除两个结点外,其余每个结点的入度=出度,
int t,n,i,j,a,b,sign; //且此两点满足deg-(u)-deg+(v)=±1.(起始点s的入度=出度-1,结束点t的出度=入度-1或两个点的入度=出度)
scanf("%d",&t); //很多题解并没有一些名词的解释,导致看的时候出现很多障碍,下面解释一下
while(t--){ //入度的意思是这一点所连接的边都把这一点作为起点的点的个数,反之出度就是为结束点的点的个数
cin>>n; //欧拉通路:通过图(无向图或有向图)中所有边且每边仅通过一次通路称为欧拉通路
for(i=0;i<1005;i++){ //欧拉回路:相应的回路称为欧拉回路
fa[i]=i;
in[i]=out[i]=vis[i]=0;
}
while(n--){
scanf("%s",s); //这个题就是判断给出的单词能否收尾链接或成欧拉回路
a=s[0]-'a'; //因此将一个单词看做一条边,首位两个字母看做两个点,求入度和出度
b=s[strlen(s)-1]-'a';
vis[a]=vis[b]=1;
in[a]++;out[b]++;
if(found(a)!=found(b)) //用并查集判断图是否联通,欧拉通路的判断前提就是图联通
fa[found(a)]=found(b);
}
sign=0;
for(i=0;i<26;i++)
if(vis[i]&&fa[i]==i){
sign++;
if(sign>1)
break;
}
if(sign>1){ //sign大于1代表除了根节点,还有根节点没有变的点,表示图不连通
printf("The door cannot be opened.\n");
continue;
}
sign=0;
for(i=0;i<26;i++){
if(vis[i]&&in[i]!=out[i])
temp[sign++]=i;
}
if(sign==0){ //代表所有点入度和出度相等形成欧拉回路
printf("Ordering is possible.\n");
continue;
}
if(sign==2){
if((in[temp[0]]-out[temp[0]]==1&&out[temp[1]]-in[temp[1]]==1)||(in[temp[1]]-out[temp[1]]==1&&out[temp[0]]-in[temp[0]]==1))
printf("Ordering is possible.\n"); //判断起始点s的入度=出度-1,结束点t的出度=入度-1
else
printf("The door cannot be opened.\n");
}
else
printf("The door cannot be opened.\n");
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/stay_accept/article/details/47749275