读完题的感觉就是网络流啦。S连向俩起点,俩终点连向T。
然而会有一个bug。
比如a1有x流到了b2,而b1有x流到了a2。这样最后也是满流,但其实是不合乎条件的。
我们可以把b1,b2调换一下位置再跑一遍,如果还是满流那么就合乎题意啦。
#include<iostream>
#include<cstdio>
#include<cstring>
#define inf 1000000007
using namespace std;
int n,T,cnt,ans;
int a[55][55];
int head[55],q[55],dis[55];
int next[5005],key[5005],list[5005];
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
inline void insert(int x,int y,int z)
{
next[++cnt]=head[x];
head[x]=cnt;
list[cnt]=y;
key[cnt]=z;
}
inline void build()
{
memset(head,0,sizeof(head)); cnt=1;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (a[i][j]==1) insert(i,j,2),insert(j,i,0);
else if (a[i][j]==2) insert(i,j,inf),insert(j,i,0);
}
inline bool BFS()
{
memset(dis,-1,sizeof(dis));
dis[0]=1; q[1]=0;
int t=0,w=1,x;
while (t!=w)
{
x=q[++t];
for (int i=head[x];i;i=next[i])
if (key[i]&&dis[list[i]]==-1)
dis[list[i]]=dis[x]+1,q[++w]=list[i];
}
return dis[T]!=-1;
}
int find(int x,int flow)
{
if (x==T) return flow;
int w,used=0;
for (int i=head[x];i;i=next[i])
if (key[i]&&dis[list[i]]==dis[x]+1)
{
w=find(list[i],min(key[i],flow-used));
key[i]-=w; key[i^1]+=w; used+=w;
if (used==flow) return flow;
}
if (!used) dis[x]=-1;
return used;
}
inline void dinic()
{
ans=0;
while (BFS()) ans+=find(0,inf);
}
int main()
{
while (scanf("%d",&n)!=EOF)
{
memset(a,0,sizeof(a)); T=n+1;
int a1,a2,an,b1,b2,bn,flag=1;
char s[55];
a1=read()+1; a2=read()+1; an=read();
b1=read()+1; b2=read()+1; bn=read();
for (int i=1;i<=n;i++)
{
scanf("%s",s+1);
for (int j=1;j<=n;j++)
if (s[j]=='O') a[i][j]=1;
else if (s[j]=='N') a[i][j]=2;
}
build();
insert(0,a1,an*2); insert(a1,0,0);
insert(0,b1,bn*2); insert(b1,0,0);
insert(a2,T,inf); insert(T,a2,0);
insert(b2,T,inf); insert(T,b2,0);
dinic();
if (ans<(an+bn)*2) flag=0;
if (flag)
{
build();
insert(0,a1,an*2); insert(a1,0,0);
insert(0,b2,bn*2); insert(b2,0,0);
insert(a2,T,inf); insert(T,a2,0);
insert(b1,T,inf); insert(T,b1,0);
dinic();
if (ans<(an+bn)*2) flag=0;
}
flag?puts("Yes"):puts("No");
}
return 0;
}