Alice和Bob居住在一个由N座岛屿组成的国家,岛屿被编号为0到N-1。某些岛屿之间有桥相连,桥上的道路是双向的,但一次只能供一人通行。其中一些桥由于年久失修成为危桥,最多只能通行两次。
Alice希望在岛屿a1和a2之间往返an次(从a1到a2再从a2到a1算一次往返)。同时,Bob希望在岛屿b1和b2之间往返bn次。这个过程中,所有危桥最多通行两次,其余的桥可以无限次通行。请问Alice和Bob能完成他们的愿望吗?
4<=N<=50
0<=a1,a2,b1,b2<=N-1
1<=an,bn<=50
n很小,考虑最大流,由于是无向图,所以一次来回只要找两条路径就可以了。
于是乎判流量是否够2(an+bn).
但会有一种问题,a1的跑到b2去了,a2的跑到b1去了.
在这种情况下,发现只需要将b的起点终点调换,这样再跑一次最大流。
因为无向边,原来a1-a2,b1-b2的肯定是全流完的,假设这两次a1-a2贡献了x,那么就有an-x流到另一边去了。
假如也可以的话,就说明有a1-b1贡献的an-x。也就是原图中可以从a1走到b1 (后一次流说明),a1也可以走到b2(前一次流说明)
两边合并一下加回到b1-b2这条路径上,对于a也是同理。
#include
#include
#include
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N = 55,inf = 1<<29;
int a1,a2,b1,b2,an,bn,n,S,T;
int final[N],to[N*N],nex[N*N],f[N*N],tot;
int gap[N],la[N];
char c[N][N];
void link(int x,int y,int fg) {to[++tot]=y,nex[tot]=final[x],final[x]=tot,f[tot]=fg;}
int go(int x,int fl) {
if (x==T) return fl;
int used=0;
for (int i=final[x]; i; i=nex[i]) if (f[i] && la[to[i]]+1==la[x]) {
int suc=go(to[i],min(fl-used,f[i]));
f[i]-=suc,f[i^1]+=suc;
used+=suc;
if (used==fl) return fl;
}
if (--gap[la[x]++]==0) la[0]=inf;
else ++gap[la[x]];
return used;
}
int maxflow() {
int ans=0; memset(gap,0,sizeof gap),memset(la,0,sizeof la);
gap[0]=n*n+2;
while (la[0]!=inf)
ans+=go(S,inf);
return ans;
}
int main() {
freopen("2.in","r",stdin);
while (scanf("%d %d %d %d %d %d %d",&n,&a1,&a2,&an,&b1,&b2,&bn)!=EOF) {
tot=1; memset(final,0,sizeof final);
a1++,a2++,b1++,b2++;
for (int i=1; i<=n; i++) {
scanf("\n"); for (int j=1; j<=n; j++) {
c[i][j]=getchar();
if (j<=i) {
if (c[i][j]=='O') link(i,j,2),link(j,i,2);
else if (c[i][j]=='N') link(i,j,inf),link(j,i,inf);
}
}
}
S=n+1,T=S+1;
link(S,a1,2*an),link(a1,S,0);
link(a2,T,2*an),link(T,a2,0);
link(S,b1,2*bn),link(b1,S,0);
link(b2,T,2*bn),link(T,b2,0);
// cout<if (maxflow()!=2*(an+bn)) {printf("No\n");continue;}
tot=1; memset(final,0,sizeof final);
for (int i=1; i<=n; i++) for (int j=1; j<=i; j++) {
if (c[i][j]=='O') link(i,j,2),link(j,i,2);
else if (c[i][j]=='N') link(i,j,inf),link(j,i,inf);
}
link(S,a1,2*an),link(a1,S,0);
link(a2,T,2*an),link(T,a2,0);
link(S,b2,2*bn),link(b2,S,0);
link(b1,T,2*bn),link(T,b1,0);
//cout<if (maxflow()!=2*(an+bn)) {printf("No\n");continue;}
printf("Yes\n");
}
}