poj-1386(欧拉回路)
题意:给你n个单词,每个单词可以和另一个单词连接,前提是(这个单词的尾字母等下一个单词的首字母),问你有没有一种连法能够连接所有的单词;
解题思路:每个单词可以看成是首字母指向尾字母的一条边,那么就变成求欧拉通路的问题了;
代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; int f[50]; int findf(int u) { if(f[u]==u) return u; else { f[u]=findf(f[u]); return f[u]; } } void join(int x,int y) { int t1=findf(x); int t2=findf(y); f[t2]=t1; } int main() { int tt; int n; int flag; int cnt1,cnt2; int father; int indeg[50]; int outdeg[50]; char t[100500]; scanf("%d",&tt); while(tt--) { memset(outdeg,0,sizeof(outdeg)); memset(indeg,0,sizeof(indeg)); for(int i=0;i<30;i++) f[i]=i; flag=cnt1=cnt2=0; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%s",t); int len=strlen(t); int x=t[0]-'a'+1; int y=t[len-1]-'a'+1; outdeg[x]++; indeg[y]++; join(x,y); father=y; } for(int i=1;i<=26;i++) { if(outdeg[i]!=0||indeg[i]!=0) { if(findf(i)!=findf(father)) flag=1; } } if(flag) { printf("The door cannot be opened.\n");continue; } for(int i=1;i<=26;i++) { if(indeg[i]!=outdeg[i]) { if(indeg[i]-outdeg[i]==1) cnt1++; else if(indeg[i]-outdeg[i]==-1) cnt2++; else { flag=1;break; } } } if(cnt1!=cnt2) { flag=1; } else { if(cnt1>1) flag=1; } if(flag) printf("The door cannot be opened.\n"); else printf("Ordering is possible.\n"); } }