链接:点击打开链接
题意:给出一些单词看能否首位相接
代码:
#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; }