您的位置:首页 > 其它

【BZOJ 3504】[Cqoi2014]危桥

2016-02-25 08:31 316 查看

Description

Alice和Bob居住在一个由N座岛屿组成的国家,岛屿被编号为0到N-1。某些岛屿之间有桥相连,桥上的道路是双

向的,但一次只能供一人通行。其中一些桥由于年久失修成为危桥,最多只能通行两次。Alice希望在岛屿al和a2之间往返an次(从al到a2再从a2
到al算一次往返)。同时,Bob希望在岛屿bl和b2之间往返bn次。这个过程中,所有危桥最多通行两次,其余的桥可以无限次通行。请问Alice和
Bob能完成他们的愿望吗?

Input

本题有多组测试数据。

每组数据第一行包含7个空格隔开的整数,分别为N、al、a2、an、bl、b2、bn。

接下来是一个N行N列的对称矩阵,由大写字母组成。矩阵的i行j列描述编号i一1和j-l的岛屿间的连接情况,若为“O”则表示有危桥相连:为“N”表示有普通的桥相连:为“X”表示没有桥相连。

|

Output

对于每组测试数据输出一行,如果他们都能完成愿望输出“Yes”,否则输出“No”。

Sample Input

4 0 1 1 2 3 1

XOXX

OXOX

XOXO

XXOX

4 0 2 1 1 3 2

XNXO

NXOX

XOXO

OXOX

Sample Output

Yes

No

数据范围

4<=N<50

O<=a1, a2, b1, b2<=N-1

1 <=an. b<=50

题解传送门

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N=60,inf=10000000;
struct ee{int to,next,f;}e[N*N*20];
int S,T,cnt=1,n,k,timer,m,u,v,w,a1,a2,an,b1,b2,bn;
char s
;
long long ans;
int head
,dis
,pre
,q
,map

;
bool inq
;
void ins(int u,int v,int f){
e[++cnt].to=v,e[cnt].next=head[u],e[cnt].f=f,head[u]=cnt;
e[++cnt].to=u,e[cnt].next=head[v],e[cnt].f=0,head[v]=cnt;
}
bool bfs(){
for (int i=1;i<=T;i++) dis[i]=inf;
int h=0,t=1,now;
q[1]=S;dis[S]=0;
while(h!=t){
now=q[++h];
for (int i=head[now];i;i=e[i].next){
int v=e[i].to;
if (e[i].f&&dis[now]+1<dis[v]){
dis[v]=dis[now]+1;
if (v==T)return 1;
q[++t]=v;
}
}
}
if (dis[T]==inf) return 0; return 1;
}

int dinic(int now,int f){
if (now==T) return f;
int rest=f;
for (int i=head[now];i;i=e[i].next){
int v=e[i].to;
if (e[i].f&&dis[v]==dis[now]+1){
int t=dinic(v,min(rest,e[i].f));
if (!t) dis[v]=0;
e[i].f-=t;
e[i^1].f+=t;
rest-=t;
}
}
return f-rest;
}

void build(){
memset(head,0,sizeof(head));cnt=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(map[i][j]==1) ins(i,j,2);
if(map[i][j]==2) ins(i,j,inf);
}
}

int main(){
while(scanf("%d%d%d%d%d%d%d",&n,&a1,&a2,&an,&b1,&b2,&bn)!=EOF){
a1++;a2++;b1++;b2++;
memset(map,0,sizeof(map));
bool flag=0;ans=0;
T=51;
for(int i=1;i<=n;i++){
scanf("%s",s+1);
for(int j=1;j<=n;j++){
if(s[j]=='O') map[i][j]=1;
if(s[j]=='N') map[i][j]=2;
}
}
build();
ins(S,a1,an*2);ins(a2,T,an*2);
ins(S,b1,bn*2);ins(b2,T,bn*2);
while(bfs())
ans+=dinic(S,inf);
if (ans<(bn+an)*2) flag=1;
if(!flag){
ans=0;
build();
ins(S,a1,an*2);ins(a2,T,an*2);
ins(S,b2,bn*2);ins(b1,T,bn*2);
while(bfs())
ans+=dinic(S,inf);
if (ans<(bn+an)*2) flag=1;
}
if(flag) printf("No\n");else printf("Yes\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: