题意:我一看欧拉回路,正好我有个板子就a了这道题了
思路:
欧拉回路就是能用一条路把所有点都连接的路没有分支,详见七桥问题
欧拉回路无非就是判断每点出度入度的是否相同,不同看看是不是起点和终点的问题即(找一个入度差一和出度也差一也行)就行,并且要用并查集判断一下是不是在一个联通快上。
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 100009;
int f[10009];
int id[1009];
int cd[1009];
int find(int x) {
if(f[x] == x) {
return x;
}
else {
return f[x] = find(f[x]);
}
}
int union1(int x, int y) {
x = find(x);
y = find(y);
if(x == y) {
return 1;
}
else {
f[x] = y;
return 0;
}
}
int main() {
int n;
scanf("%d", &n);
while(n--) {
memset(cd, 0, sizeof(cd));
memset(id, 0, sizeof(id));
int h;
scanf("%d", &h);
for(int i = 0;i <= 26;++i) {
f[i] = i;
}
for(int i = 1;i <= h;++i) {
string s;
cin >> s;
int x = s[0]-'a';
int y = s[s.length()-1]-'a';
union1(x, y);
id[y]++;
cd[x]++;
}
int sum = 0;
for(int i = 0;i < 26;++i) {
if( (id[i] || cd[i]) && find(i) == i) {
sum++;
}
}
if(sum != 1) {
printf("The door cannot be opened.\n");continue;
}
int cnt = 0, cnt1 = 0 ,cnt2 = 0, flagh = 0;
for(int i = 0;i < 26;++i) {
if(id[i] == cd[i]) {
cnt++;
}
else if(id[i]-cd[i] == 1){
cnt1++;
}
else if(cd[i]-id[i] == 1) {
cnt2++;
}
else {
flagh++;
}
}//查找头部按字典序
if((cnt1 == cnt2 && cnt1 != 1 && cnt1 != 0) || cnt1 != cnt2) {
printf("The door cannot be opened.\n");continue;
}
if(flagh) {
printf("The door cannot be opened.\n");continue;
}
printf("Ordering is possible.\n");
}
return 0;
}
/*
3
2
acm
ibm
3
acm
malform
mouse
2
ok
ok
*/