HDU1116图论

http://acm.split.hdu.edu.cn/showproblem.php?pid=1116

 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<string.h>
 5 using namespace std;
 6 const int M=30;
 7 int fa[M],vis[M],in[M],out[M],ans[M];
 8 char ch[1004];
 9 int fin(int x){
10 return fa[x]==x?fa[x]:fa[x]=fin(fa[x]);
11 }
12 int unin(int x,int y)
13 {
14 
15     return fa[fin(y)]=fin(x);
16 }
17 int main()
18 {
19    int t,n,a,b;
20    cin>>t;
21    while(t--){
22     cin>>n;
23     memset(vis,0,sizeof(vis));
24     memset(in,0,sizeof(in));
25     memset(out,0,sizeof(out));
26     for(int i=0;i<26;i++){///初始化父亲结点
27         fa[i]=i;
28     }
29     for(int i=0;i<n;i++){
30 scanf("%s",ch);
31 a=ch[0]-'a';
32 b=ch[strlen(ch)-1]-'a';
33 unin(a,b);///把字符串的开头字母和结尾字母连结起来,即是把它看作是一条有向线段
34 out[a]++;///出度
35 in[b]++;///入度
36 vis[a]=1;///标记
37 vis[b]=1;///标记
38 }
39 for(int i=0;i<26;i++)
40     fa[i]=fin(i);0///fa存储的是每个点最终的根节点
41     int cnt=0;
42     for(int i=0;i<26;i++)
43         if(vis[i]&&fa[i]==i)
44             cnt++;
45         if(cnt>1)///cnt大于1代表除啦根节点,还有根节点没有变的节点,那么此时代表图不连通
46         {
47 
48             cout<<"The door cannot be opened.
";
49             continue;
50         }
51         int j=0;
52         for(int i=0;i<26;i++){
53             if(vis[i]&&out[i]!=in[i])
54                 ans[j++]=i;
55         }
56         if(j==0){
57             cout<<"Ordering is possible.
";///j=0代表所有点的入度等于出度,此时形成欧拉回路
58             continue;
59         }
60         if(j==2&&((out[ans[0]]-in[ans[0]]==1&&
61                    in[ans[j-1]]-out[ans[j-1]]==1)
62                   ||out[ans[j-1]]-in[ans[j-1]]==1&&
63                   in[ans[0]]-out[ans[0]]==1))///此处为欧拉通路的判断,是初始节点和末尾节点的度的判断,为欧拉通路
64         {
65             cout<<"Ordering is possible.
";
66             continue;
67         }
68         cout<<"The door cannot be opened.
";
69 
70 
71    }
72 }
View Code
你若盛开,清风自来...
原文地址:https://www.cnblogs.com/shangjindexiaoqingnian/p/5823328.html