题意:给N个单词,判断是否单词首尾(前一个单词的尾字符与后一个单词的头字符相同)相连能否形成一条链。
解析:找欧拉通路(欧拉回路或是欧拉链路),但这题事先需要并查集一下,判断是否只属于一个集合,如aa,bb,cc不能形成一条链,但会判断成欧拉回路。
代码如下:
#include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<set> #include<map> #include<queue> #include<vector> #include<iterator> #include<utility> #include<sstream> #include<iostream> #include<cmath> #include<stack> using namespace std; const int INF=1000000007; const double eps=0.00000001; int N,nodenum; int d[26]; int root(int a) { while(d[a]!=a) a=d[a]; return a; } bool merg(int a,int b) //合并 { int ra=root(a); int rb=root(b); if(ra!=rb){ d[ra]=rb; return true; } return false; } int indeg[26],outdeg[26]; //入度,出度 bool vis[26]; char S[1005]; void input() { nodenum=0; cin>>N; for(int i=1;i<=N;i++) { scanf("%s",S); int pre=S[0]-‘a‘,last=S[strlen(S)-1]-‘a‘; if(!vis[pre]){ vis[pre]=true; nodenum++; } //标记并节点数加一 if(!vis[last]){ vis[last]=true; nodenum++; } outdeg[pre]++; indeg[last]++; if(merg(pre,last)) nodenum--; //减1 } } bool check() //判断是否有欧拉通路 { int f1=0,f2=0; for(int i=0;i<26;i++) { if(indeg[i]+1==outdeg[i]) f1++; else if(indeg[i]==outdeg[i]+1) f2++; else if(indeg[i]!=outdeg[i]) return false; } if((f1==0&&f2==0)||(f1==1&&f2==1)) return true; return false; } int main() { int T; cin>>T; while(T--) { for(int i=0;i<26;i++) d[i]=i; memset(vis,false,sizeof(vis)); memset(indeg,0,sizeof(indeg)); memset(outdeg,0,sizeof(outdeg)); input(); if(nodenum!=1) { printf("The door cannot be opened.\n"); continue; }//如果不等于1代表有多个集合 if(check()) printf("Ordering is possible.\n"); else printf("The door cannot be opened.\n"); } return 0; }
时间: 2024-10-06 22:37:11