有向图欧拉道路的判定,与欧拉回路类似,但要注意入度和出度的不同。
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int MAX = 26;
int T;
int N;
int graph[MAX][MAX];
int in_degree[MAX];
int out_degree[MAX];
int parent[MAX];
void initialize();
int ancestor(int x);
bool union_find_sets();
bool euler();
void initialize(){
for (int i = 0; i < MAX; i++){
parent[i] = i;
}
}
int ancestor(int x){
return parent[x] == x ? x : parent[x] = ancestor(parent[x]);
}
bool union_find_sets(){
int ai;
int aj;
for (int i = 0; i < MAX; i++){
for (int j = 0; j < MAX; j++){
if (graph[i][j]){
ai = ancestor(i);
aj = ancestor(j);
if (ai != aj){
parent[ai] = aj;
}
}
}
}
int p = 0;
for (int i = 0; i < MAX; i++){
if (in_degree[i]+out_degree[i]){
p = ancestor(i);
break;
}
}
for (int i = 0; i < MAX; i++){
if (in_degree[i]+out_degree[i]){
if (p != ancestor(i))
return false;
}
}
return true;
}
bool euler(){
int odd_point = 0;
int in_and_out = 0;
for (int i = 0; i < MAX; i++){
if (in_degree[i] - out_degree[i] == 1){
in_and_out++;
odd_point++;
}
else if (out_degree[i] - in_degree[i] == 1){
in_and_out--;
odd_point++;
}
else if (in_degree[i] != out_degree[i]){
return false;
}
}
if (odd_point == 0 || (odd_point = 2 && in_and_out == 0))
return true;
return false;
}
int main() {
cin >> T;
for (int i = 0; i < T; i++){
memset(graph,0,sizeof(graph));
memset(in_degree,0,sizeof(in_degree));
memset(out_degree,0,sizeof(out_degree));
initialize();
cin >> N;
int x;
int y;
int length;
char str[1002];
getchar();
for (int j = 0; j < N; j++){
memset(str,0,sizeof(str));
gets(str);
length = strlen(str);
x = str[0] - 'a';
y = str[length-1] - 'a';
graph[x][y]++;
out_degree[x]++;
in_degree[y]++;
}
if (union_find_sets() && euler()){
cout << "Ordering is possible." << endl;
}
else{
cout << "The door cannot be opened." << endl;
}
}
return 0;
}