图论——HDOJ 1116

来源:互联网 发布:日语语音翻译软件 编辑:程序博客网 时间:2024/06/05 06:43

HDOJ 1116 Play on Words

/*HDOJ 1116考察欧拉回路和欧拉通路的定义:首先要存在欧拉通路和欧拉回路,那么这个图必须是连通图。有向图的欧拉通路:除了有两个顶点,一个入度比出度大一,一个出度比入度大一,其他所有顶点都是出度等于入度有向图的欧拉回路:所有顶点都是出度等于入度由于这道题目是抽象为有向图,所以就只需要考虑有向图的情况就OK咯。用并查集判断是否是连通图。所以这道题目可以说是并查集和图论的结合。*/#include <iostream>#include <string>using namespace std;#define MAX 27int In[MAX];int Out[MAX];int p[MAX];int flag[MAX];int Find(int x){int y=x;while(p[y] != y)y=p[y];return y;}void Union(int a,int b){int u=Find(a);int v=Find(b);if(u != v)p[u]=v;}int main(){int nCase,n,a,b,i,f,d1,d2,d3;char str[1002];cin>>nCase;while(nCase--){for(i=0;i<MAX;i++){p[i]=i;In[i]=0;Out[i]=0;flag[i]=0;}cin>>n;for(i=0;i<n;i++){cin>>str;a=str[0]-'a';b=str[strlen(str)-1]-'a';Union(a,b);Out[a]++;In[b]++;flag[a]=flag[b]=1;}//先判断是不是连通图f=0;for(i=0;i<26;i++){p[i]=Find(i);if(flag[i] && p[i]==i)f++;}if(f>1) //非连通{cout<<"The door cannot be opened."<<endl;continue;}d1=0;d2=0;d3=0;//下面判断是否存在欧拉通(回)路for(i=0;i<26;i++){if(flag[i] && In[i]!=Out[i]){d1++;if(In[i]-Out[i] == 1)d2++;  //统计入度比出度大一的结点数else if(Out[i]-In[i] == 1)d3++;  //统计出度比入度大一的结点数}}if(d1 == 0) //存在欧拉回路cout<<"Ordering is possible."<<endl;else if((d1 == 2)&&(d2 == 1)&&(d3 == 1)) //存在欧拉通路cout<<"Ordering is possible."<<endl;elsecout<<"The door cannot be opened."<<endl;}return 0;}