题目链接:https://vjudge.net/problem/UVA-10129
分析
这道题考查的是欧拉道路和欧拉回路,可以参考刘汝佳的紫书,以下的解法按照的是书上的思路,有不对之处,请多包涵,欢迎指正。
#include<iostream>
#include<cstring>
using namespace std;
const int N = 1e5 + 10;
int a[26][26],in[26],out[26];
char s[N];
void dfs(int u)//这个连通性的判断比较难想
{
for(int v = 0; v < 26; v++)
if(a[u][v]) {
a[u][v]--;
dfs(v);
}
}
int main()
{
int T,n;
scanf("%d",&T);
while(T--) {
memset(a,0,sizeof(a));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
scanf("%d",&n);
for(int i = 0; i < n; i++) {
scanf("%s",s);
int u = s[0] - 'a',v = s[strlen(s) - 1] - 'a';
a[u][v]++;
in[v]++;out[u]++;
}
//计算奇点的个数
int flag = 1,s = 0,t = 0;
for(int i = 0; i < 26; i++)
if(in[i] != out[i]) {
if(abs(in[i] - out[i]) > 1) flag = 0;//判断是否符合欧拉道路的要求
else if(in[i] - out[i] == 1) s++;//终点
else if(out[i] - in[i] == 1) t++;//起点
}
//判断连通性
int ok = 1;
if(flag) {
//如果有两个奇点,这时候是欧拉道路
if(s == 1 && t == 1) {
for(int i = 0; i < 26; i++)
if(out[i] - in[i] == 1) {dfs(i);break;}
} else if(s + t == 0) {//没有奇点,这时候是欧拉回路
for(int i = 0; i < 26; i++)
if(out[i]) {dfs(i);break;}
} else ok = 0;
for(int i = 0; i < 26 && ok; i++) {
for(int j = 0; j < 26; j++)
if(a[i][j]) {ok = 0;break;}
}
if(ok) printf("Ordering is possible.\n");
else printf("The door cannot be opened.\n");
} else printf("The door cannot be opened.\n");
}
return 0;
}