Yes
No
数据范围
4<=N<50
O<=a1, a2, b1, b2<=N-1
1 <=an. b<=50
解题思路:
神题。。。 网上证明好像有问题。。
就是先建图,跑最大流,看ans是否是2*an+2*bn。
满足的话,将b1,b2交换再做,再判断,如果还满足就满足。
以后遇到这种题的话,实在不会证,就看看是否是满足对称性的,再考虑交换来做。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define inf 0x7fffffff
#define ll long long
#define T 51
using
namespace
std
;
bool
flag
;
int
n
,
a1
,
a2
,
an
,
b1
,
b2
,
bn
;
int
cnt
,
ans
;
int
h
[
55
]
,
q
[
55
]
;
int
mp
[
55
]
[
55
]
;
struct
data
{
int
to
,
next
,
v
;
}
e
[
100005
]
;
int
head
[
55
]
,
cur
[
55
]
;
void
ins
(
int
u
,
int
v
,
int
w
)
{
e
[
++
cnt
]
.
to
=
v
;
e
[
cnt
]
.
next
=
head
[
u
]
;
head
[
u
]
=
cnt
;
e
[
cnt
]
.
v
=
w
;
}
void
insert
(
int
u
,
int
v
,
int
w
)
{
ins
(
u
,
v
,
w
)
;
ins
(
v
,
u
,
0
)
;
}
void
build
(
)
{
memset
(
head
,
0
,
sizeof
(
head
)
)
;
cnt
=
1
;
for
(
int
i
=
1
;
i
<=
n
;
i
++
)
for
(
int
j
=
1
;
j
<=
n
;
j
++
)
if
(
mp
[
i
]
[
j
]
==
1
)
insert
(
i
,
j
,
2
)
;
else
if
(
mp
[
i
]
[
j
]
==
2
)
insert
(
i
,
j
,
inf
)
;
}
bool
bfs
(
)
{
int
t
=
0
,
w
=
1
;
for
(
int
i
=
0
;
i
<=
T
;
i
++
)
h
[
i
]
=
-
1
;
q
[
0
]
=
0
;
h
[
0
]
=
0
;
while
(
t
!=
w
)
{
int
now
=
q
[
t
]
;
t
++
;
for
(
int
i
=
head
[
now
]
;
i
;
i
=
e
[
i
]
.
next
)
if
(
e
[
i
]
.
v
&&
h
[
e
[
i
]
.
to
]
==
-
1
)
{
h
[
e
[
i
]
.
to
]
=
h
[
now
]
+
1
;
q
[
w
++
]
=
e
[
i
]
.
to
;
}
}
if
(
h
[
T
]
==
-
1
)
return
0
;
return
1
;
}
int
dfs
(
int
x
,
int
f
)
{
if
(
x
==
T
)
return
f
;
int
w
,
used
=
0
;
for
(
int
i
=
cur
[
x
]
;
i
;
i
=
e
[
i
]
.
next
)
{
if
(
e
[
i
]
.
v
&&
h
[
e
[
i
]
.
to
]
==
h
[
x
]
+
1
)
{
w
=
f
-
used
;
w
=
dfs
(
e
[
i
]
.
to
,
min
(
e
[
i
]
.
v
,
w
)
)
;
e
[
i
]
.
v
-=
w
;
if
(
e
[
i
]
.
v
)
cur
[
x
]
=
i
;
e
[
i
^
1
]
.
v
+=
w
;
used
+=
w
;
if
(
used
==
f
)
return
f
;
}
}
if
(
!
used
)
h
[
x
]
=
-
1
;
return
used
;
}
void
dinic
(
)
{
while
(
bfs
(
)
)
{
for
(
int
i
=
0
;
i
<=
T
;
i
++
)
cur
[
i
]
=
head
[
i
]
;
ans
+=
dfs
(
0
,
inf
)
;
}
}
int
main
(
)
{
while
(
scanf
(
"%d%d%d%d%d%d%d"
,
&n
,
&a1
,
&a2
,
&an
,
&b1
,
&b2
,
&bn
)
!=
EOF
)
{
memset
(
mp
,
0
,
sizeof
(
mp
)
)
;
flag
=
0
;
a1
++
;
a2
++
;
b1
++
;
b2
++
;
for
(
int
i
=
1
;
i
<=
n
;
i
++
)
{
char
ch
[
55
]
;
scanf
(
"%s"
,
ch
)
;
for
(
int
j
=
1
;
j
<=
n
;
j
++
)
if
(
ch
[
j
-
1
]
==
'O'
)
mp
[
i
]
[
j
]
=
1
;
else
if
(
ch
[
j
-
1
]
==
'N'
)
mp
[
i
]
[
j
]
=
2
;
}
build
(
)
;
insert
(
0
,
a1
,
an
*
2
)
;
insert
(
a2
,
T
,
an
*
2
)
;
insert
(
0
,
b1
,
bn
*
2
)
;
insert
(
b2
,
T
,
bn
*
2
)
;
ans
=
0
;
dinic
(
)
;
if
(
ans
<
2
*
(
an
+
bn
)
)
flag
=
1
;
if
(
!
flag
)
{
build
(
)
;
insert
(
0
,
a1
,
an
*
2
)
;
insert
(
a2
,
T
,
an
*
2
)
;
insert
(
0
,
b2
,
bn
*
2
)
;
insert
(
b1
,
T
,
bn
*
2
)
;
ans
=
0
;
dinic
(
)
;
if
(
ans
<
2
*
(
an
+
bn
)
)
flag
=
1
;
}
if
(
flag
)
printf
(
"No\n"
)
;
else
printf
(
"Yes\n"
)
;
}
return
0
;
}