题目描述:
题目思路:
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 }