单词 (Play on Words UVA - 10129 )

题目描述:

原题:https://vjudge.net/problem/UVA-10129

 

题目思路:

1.明显是判断欧拉路径

2.欧拉路径的两个条件

  a.图连通

  b.至多为两个奇点,且一个为起点一个为重点

3.连通还是用DFS判断,奇点在输入时开两个数组统计出入度

AC代码
 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 const int maxn = 26 + 5 ;
 6 int G[maxn][maxn],vis[maxn]; //图的实现和访问标记 
 7 int ind[maxn],outd[maxn]; //出入度的统计
 8 char str[1005];
 9 
10 void dfs(int u) 
11 {
12     vis[u] = 1 ;//访问标记
13     for(int i = 0;i < maxn;i ++)
14         if(!vis[i] && G[u][i]) dfs(i) ; 
15 } 
16  
17 int main(int argc, char *argv[])
18 {
19     int t;
20     cin >> t;
21     while(t--)
22     {
23         int n;
24         cin >> n ;
25         
26         memset(G,0,sizeof(str)) ;
27         memset(ind,0,sizeof(ind));
28         memset(outd,0,sizeof(outd)) ;
29         for(int i = 0;i < n;i ++)
30         {
31             cin >> str ;
32             int len = strlen(str);
33             ++G[str[0] - 'a'][str[len-1] - 'a'] ; //字母为结点,单词为边 
34             ++ind[str[len-1] - 'a'] ; //出入度的统计 
35             ++outd[str[0] - 'a'] ;
36         }
37         
38         bool flag = true ;
39         int cnt1 = 0,cnt2 = 0;
40         for(int i = 0;i < maxn;i ++)
41         {
42             if(ind[i] != outd[i]){
43                 if(ind[i] == outd[i] + 1) cnt1++ ;//可能为起点的奇点
44                 else if(ind[i] + 1 == outd[i]) cnt2++ ;
45                 else{
46                     flag = false; //出入度相差大于1,不符合欧拉路径 
47                     break ;
48                 }        
49             }    
50         } 
51         if(cnt1 && cnt2 && cnt1+cnt2 > 2) flag = false ;// 奇点存在且大于2,不符合欧拉路径
52         
53         if(flag) //如果符合欧拉路径,dfs判断图是否连通 
54         {
55             memset(vis,0,sizeof(vis)) ;
56             //两种情况,两个奇点,则必从其中一个为起点
57             if(cnt1 + cnt2 == 2)
58             {
59                 for(int i = 0;i < maxn;i ++)
60                     if(outd[i] && outd[i] - ind[i] == 1) //找起点
61                         {dfs(i); break;} 
62             }
63             else
64             {
65                 for(int i = 0;i < maxn;i ++)
66                     if(outd[i])    {dfs(i); break;} 
67             }
68             
69             bool tag = true;
70             //如果此时还有未访问到的点,则图不连通,不符合欧拉路径
71             for(int i = 0;i < maxn;i ++)
72             {
73                 if(outd[i]&&!vis[i]) {
74                     tag = false; break;
75                 }
76                 if(ind[i]&&!vis[i]) {
77                     tag = false; break;
78                 }
79             }
80             if(tag) cout << "Ordering is possible."<< endl;
81             else cout << "The door cannot be opened." << endl;        
82         }
83         else cout << "The door cannot be opened." << endl;
84          
85     }    
86     return 0;
87 }

 

转载于:https://www.cnblogs.com/secoding/p/9539555.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值