hdu 1116 Play on Words

http://acm.hdu.edu.cn/showproblem.php?pid=1116   将每一个单词的首尾字母当做结点,首尾字母间连线,判断最后形成的有向图能否形成欧拉通路。
欧拉通路:除首尾结点外,其余结点入度等于出度,起点出度减入度等于1,终点入度减出度等于1。
 欧拉回路:所有结点的入度都等于出度。

View Code
 1 #include<iostream>
2 #include<cstring>
3 #include<cstdlib>
4 using namespace std;
5 const int N=30;
6 int father[N],in[N],out[N],flag[N],a[N];//a记录入度不等于初度的点
7 void initSet()
8 {
9 for(int i=0;i<N;i++) father[i]=i;
10 }
11 int find(int x)
12 {
13 int i=x,temp;
14 while(i!=father[i]) i=father[i];
15 while(x!=i)
16 {
17 temp=father[x];
18 father[x]=i;
19 x=temp;
20 }
21 return i;
22 }
23 void unionSet(int a,int b)
24 {
25 int fatherx=find(a);
26 int fathery=find(b);
27 if(fatherx!=fathery) father[fatherx]=fathery;//
28 }
29 int main()
30 {
31 int t,n;
32 cin>>t;
33 while(t--)
34 {
35 cin>>n;
36 initSet();
37 memset(flag,0,sizeof(flag));
38 memset(in,0,sizeof(in));
39 memset(out,0,sizeof(out));
40 memset(a,0,sizeof(a));
41 int i,j,x,y;
42 string s;
43 for(i=0;i<n;i++)
44 {
45 cin>>s;
46 x=s[0]-'a';
47 y=s[s.length()-1]-'a';
48 unionSet(x,y);//字母头指向字母尾
49 flag[x]=flag[y]=1;//用来标记处理过的字母
50 in[x]++;
51 out[y]++;//初度,入度
52 }
53 int cnt=0;
54 for(i=0;i<N;i++)
55 {
56 if(flag[i] && find(i)==i) cnt++;
57 //if(flag[i]) cout<<"father["<<char(i+'a')<<"]:"<<char('a'+find(i))<<endl;
58 }
59 if(cnt>1)//不是连通图
60 cout<<"The door cannot be opened."<<endl;
61 else
62 {
63 j=0;
64 for(i=0;i<N;i++)
65 if(flag[i] && in[i]!=out[i]) a[j++]=i;//记录入度不等于初度的点
66 //j==0 是欧拉回路
67 if(j==0) {cout<<"Ordering is possible."<<endl;continue;}
68 x=a[0],y=a[1];
69 /* 欧拉回路:所有点入度==初度
70 欧拉通路:起点初度-入度==1,终点入度-初度==1,其余初度==入度
71 if(j==2 && (in[x]-out[x]==1 && out[y]-in[y]==1 ||
72 in[y]-out[y]==1 && out[x]-in[x]==1))
73 cout<<"Ordering is possible."<<endl;
74 else cout<<"The door cannot be opened."<<endl;
75 }
76 }
77 return 0;
78 }


 

posted @ 2012-04-03 23:14  keepmoving89  阅读(211)  评论(0编辑  收藏  举报