HDU 1116 Play on Words(并查集,欧拉回路)

//ashione 2011-6-1 ,并查集,欧拉回路检测 #include<iostream> #include<cstring> using namespace std; #define SetMax 27 #define StringMax 1001 int set[SetMax],in[SetMax],out[SetMax],point[SetMax]; char temp[StringMax]; bool mark[SetMax],falg; int find(int a){ //查找集合的根 return a==set[a]?a:set[a]=find(set[a]); } void merge(int a,int b){//合并集合 mark[a]=mark[b]=true; int x=find(a),y=find(b); if(x!=y) set[x]=y; } void init(){//初始化数据,in为所有的入度,out为所有的出度 memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); memset(mark,false,sizeof(mark)); for(int i=0;i<26;i++) set[i]=i; } int subin_out(){ //判断回路的两端点是否满足欧拉通路 return (in[point[0]]-out[point[0]])*(out[point[1]]-in[point[1]]); } int main(){ int t,n,i,j,k; cin>>t; while(t--){ cin>>n; init(); for(i=0;i<n;i++){ cin>>temp; int x=temp[0]-'a',y=temp[strlen(temp)-1]-'a'; merge(x,y); out[x]++,in[y]++; } int cn=0; for(i=0;i<26;i++) if(mark[i] && set[i]==i) cn++; if(cn>1){ //连通分量的个数,大于1则不连通 cout<<"The door cannot be opened."<<endl; continue; } k=0; for(i=0;i<26;i++) if(in[i]!=out[i]) point[k++]=i;//统计度数不相等的点 if(!k|| (k==2 && subin_out()==1 )) //当K=0时所有出度入度相等为欧拉回路,函数判断是否为欧拉通路。 cout<<"Ordering is possible."<<endl; else cout<<"The door cannot be opened."<<endl; } return 0; }

你可能感兴趣的:(HDU 1116 Play on Words(并查集,欧拉回路))