【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 1XOXX
OXOX
XOXO
XXOX
4 0 2 1 1 3 2
XNXO
NXOX
XOXO
OXOX
Sample Output
YesNo
数据范围
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"); } }
相关文章推荐
- 极路由下打不开soundcloud怎么办?
- 如何取消:win7拖动桌面快捷方式到回收站,提示:这些文件可能对你的计算机有害
- kobox: key_proc.c -v1 怎样使用proc文件系统调试驱动
- java练习题,比较两数大小
- Linux服务启动报:Address already in use 解决方法:预留端口避免占用ip_local_reserved_ports
- 轻松实现本地存储(LocalStorage)-store.js
- 坐标系的转换
- HD7 使用点滴
- 语法分析器(java)
- [Regionals 2012 :: Asia - Tokyo ]
- Phone 7编程点滴
- C#连接MySQL数据库的几点注意
- 【BZOJ 1090】[SCOI2003]字符串折叠
- TypeScript Interface(接口)
- NS2下实现一个无线网络广播包的大致流程
- 黑马程序员-----------浅谈多线程
- JSP自定义标签继承哪个类
- lintcode-easy-Identical Binary Tree
- Cygwin 安装
- 【BZOJ1026】[SCOI2009]windy数【数位DP】