题目链接:
#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的顶点, 其他顶点入度=出度 那么这个图是欧拉通路
当满足图连通时, 所有顶点入度=出度 那么这个图是欧拉回路
代码:
时间: 2024-11-07 16:48:38