hdoj Play on Words
#include <iostream>
#include <cstring>
using namespace std;
const int N = 27;
typedef struct
{
int in_degree;//记录入度
int out_degree;//记录出度
}Point;
typedef struct
{
int parent;
int height;
}Node;
Point degree[N];
Node UFSet[N];
bool Visited[N];
int record[N], cnt;//此数组用于记录出现的字符
void init()
{//初始化入度和出度,初始化并查集
int i;
for(i = 0; i < N; i++)
{
degree[i].in_degree = degree[i].out_degree = 0;
UFSet[i].parent = i;
UFSet[i].height = 1;
Visited[i] = false;
}
cnt = 0;
}
int find(int x)
{//并查集之查操作
while(x != UFSet[x].parent)
x = UFSet[x].parent;
return x;
}
void merge(int x, int y)
{
if(x == y)
return ;
if(UFSet[x].height == UFSet[y].height)
{
UFSet[y].parent = x;
UFSet[x].height++;
}
else if(UFSet[x].height > UFSet[y].height)
UFSet[y].parent = x;
else
UFSet[x].parent = y;
}
int main()
{
int T;
int n, a, b , i;
int sum;
bool flag;
char str[1003];
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
init();
for(i = 0; i < n; i++)
{
scanf("%s", str);
a = str[0] - 'a';
b = str[strlen(str) - 1] - 'a';
if(!Visited[a])
{
Visited[a] = true;
record[cnt++] = a;
}
if(!Visited[b])
{
Visited[b] = true;
record[cnt++] = b;
}
/**//////////入度,出度的统计///////////
degree[b].in_degree++;
degree[a].out_degree++;
/**////////////并查集操作/////////
a = find(a);
b = find(b);
merge(a, b);
}
flag = false;
a = find(record[0]);
for(i = 1; i < cnt; i++)
if(a != find(record[i]))
{
flag = true;
break;
}
if(flag)
{//此为用并查集判连通
printf("The door cannot be opened.\n");
continue;
}
sum = a = b = 0; flag = true;
for(i = 0; i < cnt && sum < 3; i++)
{
if(degree[record[i]].in_degree != degree[record[i]].out_degree)
{
sum++;
if(degree[record[i]].in_degree == degree[record[i]].out_degree + 1)
a++;
else if(degree[record[i]].in_degree + 1 == degree[record[i]].out_degree)
b++;
else
{
flag = false;
break;
}
}
}
if(flag && a == b)
printf("Ordering is possible.\n");
else
printf("The door cannot be opened.\n");
}
return 0;
}