判断欧拉道路。
欧拉道路的定义是: 除了起点和终点外, 其他点的出度入度相等。
题意是给你很多字符串,问是否可以让这些字符串守卫相连在一起,要求其中一个的尾字母和另一个首字母相同才可连接。
用一个二维数组g[ ] [ ],存储首位字母,看作边的两个结点,然后再进行判断。(因为连接时可以存在回路,所以不能单纯认为一定有两个出度入度不同的点。)
用dfs来连接图,最后判断图是否全部连接起来即可。
代码:
#include <iostream>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#define maxn 105
using namespace std;
int n;
int G[maxn][maxn];
int in[maxn];//入度
int out[maxn];//出度
int vis[maxn];
void dfs(int u){
vis[u] = 1;
for(int i = 0; i < maxn; i++){
if(G[u][i] && !vis[i])
dfs(i);
}
}
int main()
{
int t; cin >> t;
while(t--)
{
cin >> n;
string s;
memset(G, 0, sizeof(G));
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
for(int i = 1; i <= n; i++)
{
cin >> s;
G[s[0]-'a'][s[s.size()-1]-'a'] = 1;
in[s[s.size()-1]-'a']++;
out[s[0]-'a']++;
}
int num1 = 0, num2 = 0;
bool flag = true;
for(int i = 0; i < maxn; i++)
{
if(!flag) break;
if(in[i] != out[i]){
if(in[i] == out[i]+1) {num1++;}
else if(out[i] == in[i]+1) {num2++;}
else {flag = false; break;}
}
}
if(!(num1 == 1 && num2 == 1) && !(num1 == 0 || num2 == 0)) flag = false;
if(flag)
{
memset(vis, 0, sizeof(vis));
for(int i = 0; i < maxn; i++)//联通起来,用vis数组存储是否连通过
if(out[i]) {
dfs(i); break;
}
bool flag2 = true;
for(int i = 0; i < maxn; i++){
if(in[i] && !vis[i]) {flag2 = false; break; }
if(out[i] && !vis[i]) {flag2 = false; break; }
}
if(flag2) printf("Ordering is possible.\n");
else printf("The door cannot be opened.\n");
}
else
printf("The door cannot be opened.\n");
}
return 0;
}