首先这个题,我以为是DFS。。。交上各种TLE ,RE,暴栈和超时啊。。。找了一下题解,发现是图论问题。。。唉。
又重新翻离散课本。。。定理:有向图的欧拉路连通且存在一个出度比入度大一的,存在一个入度比出度大一的,其他入度出度相等。有向图欧拉回路连通且入度出度都相等。
交上WA,然后查错,总以为是 判断是否是联通的时候做错了,其实是 忘记判断也是欧拉回路了。。。悲剧。。。代码 好烂。
#include <stdio.h>
#include
<
string
.h>
#include
<stdlib.h>
int
p[
27
][
27
],z,n,o[
27
],key[
27
];
int
find(
int
x)
{
int
r,t;
r
=
x;
while
(x !=
o[x])
x
=
o[x];
while
(r !=
x)
{
t
=
o[r];
o[r]
=
x;
r
=
t;
}
return
x;
}
void
merge(
int
x,
int
y)
{
x
=
find(x);
y
=
find(y);
if
(x !=
y)
o[x]
=
y;
}
int
main()
{
int
t,i,j,sum,start,end,len,sum1,sum2,k1,k2;
char
str[
1001
];
scanf(
"
%d%*c
"
,&
t);
while
(t--
)
{
z
=
1
;k1 = k2 =
0
;
memset(p,
0
,
sizeof
(p));
memset(key,
0
,
sizeof
(key));
for
(i =
1
;i <=
26
;i ++
)
o[i]
=
i;
scanf(
"
%d%*c
"
,&
n);
for
(i =
1
;i <= n;i ++
)
{
scanf(
"
%s
"
,str);
len
=
strlen(str);
start
= str[
0
] -
'
a
'
+
1
;
end
= str[len-
1
] -
'
a
'
+
1
;
key[start]
= key[end] =
1
;
merge(start,end);
p[start][end]
++
;
}
for
(i =
1
;i <=
26
;i ++
)
{
if
(key[i])
break
;
}
sum
=
find(i);
for
(j = i+
1
;j <=
26
;j ++
)
{
if
(find(j) != sum &&
key[j])
break
;
}
if
(j !=
27
)
z
=
0
;
for
(i =
1
;i <=
26
&&z;i ++
)
{
sum1
= sum2 =
0
;
for
(j =
1
;j <=
26
;j ++
)
{
sum1
+=
p[i][j];
sum2
+=
p[j][i];
}
if
(sum1 ==
sum2)
;
else
if
(sum1 == sum2+
1
)
{
k1
++
;
}
else
if
(sum1+
1
==
sum2)
{
k2
++
;
}
else
{
z
=
0
;
break
;
}
}
if
(z)
{
if
(k1==
1
&&k2==
1
)
printf(
"
Ordering is possible.\n
"
);
else
if
(k1==
0
&&k2==
0
)
printf(
"
Ordering is possible.\n
"
);
else
printf(
"
The door cannot be opened.\n
"
);
}
else
printf(
"
The door cannot be opened.\n
"
);
}
return
0
;
}

