题面

传送门

思路

这道题中惟一的特别之处,就在于“危桥”这一个只能走两次的东西

我的第一想法是做一个dp,但是这道题只需要能不能走,也没有必要

网络流?貌似是个很好的选择

我们把所有边作为无向边加入图中,流量上限inf

危桥则作为上限2的无向边

从源点连边到a1b1,汇点连边到a2b2,流量都是2*an或2*bn,相当于一次把两遍走了

最后,只要看看最大流不是(2*an+2*bn)

然而有个问题,万一我们最终求得的最大流中,是a1流到b2、b1流到a2呢?

此时有一个好办法:我们把源点连边到a1b2,汇点连边到a2b1,如果还能满流,就OK了

具体为什么?自己画图理解一下即可~

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define inf 1e9
using namespace std;
int n,cnt=-1,first[110],dep[110],cur[110],a1,a2,an,b1,b2,bn;
struct edge{
int to,next,w;
}a[10010];
inline void add(int u,int v,int w){
a[++cnt]=(edge){v,first[u],w};first[u]=cnt;
a[++cnt]=(edge){u,first[v],w};first[v]=cnt;
}
bool bfs(int s,int t){
int q[110],head=0,tail=1,u,v,i;
for(i=s;i<=t;i++) dep[i]=-1,cur[i]=first[i];
q[0]=s;dep[s]=0;
while(head<tail){
u=q[head++];
for(i=first[u];~i;i=a[i].next){
v=a[i].to;
if(~dep[v]||!a[i].w) continue;
dep[v]=dep[u]+1;q[tail++]=v;
}
}
return ~dep[t];
}
int dfs(int u,int t,int limit){
if(u==t||!limit) return limit;
int i,v,f,flow=0;
for(i=first[u];~i;i=a[i].next){
v=a[i].to;
if(dep[v]==dep[u]+1&&(f=dfs(v,t,min(limit,a[i].w)))){
a[i].w-=f;a[i^1].w+=f;
flow+=f;limit-=f;
if(!limit) return flow;
}
}
return flow;
}
int dinic(int s,int t){
int re=0;
while(bfs(s,t)) re+=dfs(s,t,inf);
return re;
}
void init(){memset(first,-1,sizeof(first));memset(a,0,sizeof(a));cnt=-1;}
int e[110][110];
int main(){
int i,j,tmp1,tmp2;char s[110];
while(~scanf("%d%d%d%d%d%d%d",&n,&a1,&a2,&an,&b1,&b2,&bn)){
init();a1++;a2++;b1++;b2++;
for(i=1;i<=n;i++){
scanf("%s",s);
for(j=1;j<=n;j++){
if(s[j-1]=='X') e[i][j]=0;
if(s[j-1]=='O') e[i][j]=2;
if(s[j-1]=='N') e[i][j]=1;
}
}
for(i=1;i<=n;i++){
for(j=i+1;j<=n;j++){
if(e[i][j]) add(i,j,((e[i][j]==1)?inf:2));
}
}
add(0,a1,an<<1);add(0,b1,bn<<1);add(a2,n+1,an<<1);add(b2,n+1,bn<<1);
tmp1=dinic(0,n+1);
init();
for(i=1;i<=n;i++){
for(j=i+1;j<=n;j++){
if(e[i][j]) add(i,j,((e[i][j]==1)?inf:2));
}
}
add(0,a1,an<<1);add(0,b2,bn<<1);add(a2,n+1,an<<1);add(b1,n+1,bn<<1);
tmp2=dinic(0,n+1);
if((tmp1!=(an<<1)+(bn<<1))||(tmp2!=(an<<1)+(bn<<1))) puts("No");
else puts("Yes");
}
}

最新文章

  1. Shader实例:扭曲,漩涡
  2. 使用flume-ng聚合双活Nginx日志
  3. CentOS双网卡绑定bond0
  4. sim800 gprs发送数据的AT流程
  5. 题目: 求1+2+...+n,要求不使用乘除发、for、while、if、else、switch、case、等关键字以及条件判断语句(A?B:C)
  6. Java--如何使用sun.misc.Unsafe完成compareAndSwapObject原子操作
  7. DzzOffice结合office web Apps私有部署的实例
  8. 动态加载JS(css)文件
  9. yii 分页样式
  10. 程序猿必备的10款web前端开发插件一
  11. Codeforces_499C:Crazy Town(计算几何)
  12. C#设计模式之十七观察者模式(Observer Pattern)【行为型】
  13. Go语言协程
  14. 安装eclipse scala插件
  15. Java 多线程之Timer与ScheduledExecutorService
  16. ssh免密登陆配置
  17. 5阶m序列
  18. linux命令之 df file fsck fuser
  19. C. Meme Problem
  20. php -- 魔术方法、魔术常量 简单介绍

热门文章

  1. 2018.5.30 Oracle数据库PLSQL编程---游标的使用
  2. 2017.12.11 String 类中常用的方法
  3. EM理解(转)
  4. C#继承机制 访问与隐藏基类成员
  5. c++异常处理--创建自己的异常处理类
  6. mysql基础,数据表的类型
  7. 入门学习Linux常用必会命令实例详解
  8. java设计模式2--工厂模式
  9. vscode运行C/C++程序及配置
  10. Nordic Collegiate Programming Contest (NCPC) 2016