一开始想了一发费用流做法然后直接出负环了

首先,比较显然的思路就是对于原图中没有限制的边,对应的流量就是\(inf\),如果是危桥,那么流量就应该是\(2\)。

由于存在两个起始点,我们考虑直接\(s->a_1,s->b_1\)

然后对于终点,\(a_2->t,b_2->t\)

流量分别是次数的两倍!

(因为往返相当于跑双倍的单程)

然后跑最大流,看一下流量是不是\((2\times (a_n+b_n))\)

但是这样会存在一个瑕疵。就是跑出来的路径是\(a_1->b_2\)

那么这时候,我们选择交换\(b_1和b_2\)的位置,然后重新建图跑最大流。

如果流量还是那个值,那就是\(yes\)。

这是为什么呢?如果两次都是等于\(2\times (a_n+b_n)\),那么只存在两种情况,要么是\(a_1->a_2\)是可行的,要么就是存在\(b1->a1->b2\)这样一条路径且路径的流量是\(2*b_n\),另一边同理。

所以当两次的流量都是合法的时候,那么一定就是\(Yes\),否则就是\(No\)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define mk make_pair
#define ll long long
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int maxn = 3010;
const int maxm = 2e6+1e2;
const int inf = 1e9;
int point[maxn],nxt[maxm],to[maxm];
int flow[maxm],val[maxm];
int cnt=1,n,m;
int pre[maxm],from[maxn];
int dis[maxn],vis[maxn];
int num;
int s,t;
void addedge(int x,int y,int w)
{
nxt[++cnt]=point[x];
to[cnt]=y;
point[x]=cnt;
val[cnt]=w;
}
void insert(int x,int y,int w)
{
addedge(x,y,w);
addedge(y,x,0);
}
int h[maxn];
queue<int> q;
bool bfs(int s)
{
memset(h,-1,sizeof(h));
h[s]=0;
q.push(s);
while (!q.empty())
{
int x=q.front();
q.pop();
for (int i=point[x];i;i=nxt[i])
{
int p = to[i];
if (h[p]==-1 && val[i]>0)
{
q.push(p);
h[p]=h[x]+1;
}
}
}
if (h[t]==-1) return false;
return true;
}
int dfs(int x,int low)
{
if (x==t || low==0) return low;
int totflow=0;
for (int i=point[x];i;i=nxt[i])
{
int p = to[i];
if (h[p]==h[x]+1 && val[i]>0)
{
int tmp = dfs(p,min(low,val[i]));
val[i]-=tmp;
val[i^1]+=tmp;
totflow+=tmp;
low-=tmp;
if(low==0) return totflow;
}
}
if(low>0) h[x]=-1;
return totflow;
}
int dinic()
{
int ans=0;
while (bfs(s))
{
ans=ans+dfs(s,inf);
}
return ans;
}
int a,b,c,d,e,f;
char ss[1010][1010];
void init()
{
cnt=1;
memset(point,0,sizeof(point));
memset(from,0,sizeof(from));
}
int main()
{
while(scanf("%d%d%d%d%d%d%d",&n,&a,&b,&c,&d,&e,&f)!=EOF)
{
init();
a++;
b++;
e++;
d++;
for (int i=1;i<=n;i++)
{ scanf("%s",ss[i]+1);
for (int j=1;j<=n;j++)
{
if (ss[i][j]=='X') continue;
if (ss[i][j]=='O') insert(i,j,2);
if (ss[i][j]=='N') insert(i,j,inf);
}
}
int tag=0;
s=maxn-10;
t=s+1;
insert(s,a,2*c);
insert(b,t,2*c);
insert(s,d,2*f);
insert(e,t,2*f);
if (dinic()==2*(c+f)) tag++;
init();
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
{
if (ss[i][j]=='X') continue;
if (ss[i][j]=='O') insert(i,j,2);
if (ss[i][j]=='N') insert(i,j,inf);
}
}
insert(s,a,2*c);
insert(b,t,2*c);
insert(s,e,2*f);
insert(d,t,2*f);
if (dinic()==2*(c+f)) tag++;
if(tag==2)
{
cout<<"Yes\n";
}
else
{
cout<<"No\n";
}
}
return 0;
}

洛谷3163 CQOI2014危桥 (最大流)的更多相关文章

  1. BZOJ 3504: [Cqoi2014]危桥 [最大流]

    3504: [Cqoi2014]危桥 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1407  Solved: 703[Submit][Status] ...

  2. BZOJ.3504.[CQOI2014]危桥(最大流ISAP)

    BZOJ 洛谷 这种题大多是多源多汇跑网络流.往返\(a_n/b_n\)次可以看做去\(a_n/b_n\)次,直接把危桥能走的次数看做\(1\). 先不考虑别的,直接按原图建模:危桥建双向边容量为\( ...

  3. bzoj3504: [Cqoi2014]危桥--最大流

    题目大意:给张无向图,有两个人a,b分别从各自的起点走向各自的终点,走A,B个来回,图里有些边只能走两次,求问是否能满足a,b的需求 按照题目给的表建图 S连a1,b1 a2,b2连T 跑最大流看是否 ...

  4. Luogu3163 [CQOI2014]危桥 ---- 网络流 及 一个细节的解释

    Luogu3163 [CQOI2014]危桥 题意 有$n$个点和$m$条边,有些边可以无限次数的走,有些边这辈子只能走两次,给定两个起点和终点$a_1 --> a_2$(起点 --> 终 ...

  5. 3504: [Cqoi2014]危桥

    3504: [Cqoi2014]危桥 链接 分析: 首先往返的可以转化为全是“往”,那么只要将容量除以2即可. 然后S向a1连边容量为an(除以2之前为2*an),S向a2连边容量为an,b1,b2向 ...

  6. bzoj千题计划137:bzoj [CQOI2014]危桥

    http://www.lydsy.com/JudgeOnline/problem.php?id=3504 往返n遍,即单向2*n遍 危桥流量为2,普通桥流量为inf 原图跑一遍最大流 交换b1,b2再 ...

  7. [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码

    [洛谷P3376题解]网络流(最大流)的实现算法讲解与代码 更坏的阅读体验 定义 对于给定的一个网络,有向图中每个的边权表示可以通过的最大流量.假设出发点S水流无限大,求水流到终点T后的最大流量. 起 ...

  8. AC日记——[CQOI2014]危桥 洛谷 P3163

    题目描述 Alice和Bob居住在一个由N座岛屿组成的国家,岛屿被编号为0到N-1.某些岛屿之间有桥相连,桥上的道路是双向的,但一次只能供一人通行.其中一些桥由于年久失修成为危桥,最多只能通行两次.A ...

  9. BZOJ3504 CQOI2014危桥(最大流)

    如果只有一个人的话很容易想到最大流,正常桥连限流inf双向边,危桥连限流2双向边即可.现在有两个人,容易想到给两起点建超源两汇点建超汇,但这样没法保证两个人各自到达自己要去的目的地.于是再超源连一个人 ...

随机推荐

  1. 带你走进MySQL全新高可用解决方案-MGR

    ​一.初识MGR 相信很多人对MGR这个词比较陌生,其实MGR(全称 MySQL Group Replication [MySQL 组复制])是Oracle MySQL于2016年12月发布MySQL ...

  2. java深度复制

    索要克隆的类必须实现:Serializable,Cloneable接口import java.io.ByteArrayInputStream; import java.io.ByteArrayOutp ...

  3. idea导出jar包及坑

    导出基本步骤 1.打开项目结构,在artifact新建一个jar 2.然后填写主类和依赖 3.这里的坑: 4.查看 5.点击编译输出 6.得到jar包

  4. 理解ASP.NET Core - [03] Dependency Injection

    注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 依赖注入 什么是依赖注入 简单说,就是将对象的创建和销毁工作交给DI容器来进行,调用方只需要接 ...

  5. VS Code闪现,巨头纷纷入局的Web IDE缘何崛起?

    我发了,我装的. 就在前几天,微软简短的发布了Visual Studio Code for the Web 的公告,而没过一阵,这则公告就被删除了,现在点经相关内容已经是404状态了.虽然公告的内容已 ...

  6. C#新版本风格(NetCore)项目文件

    在VisualStudio中创建NetCore以上版本的项目,使用的都是新版本风格的项目文件. 和旧版本.NetFramework版本的项目文件区别: 双击项目可直接打开csproj文件进行编辑配置 ...

  7. Python - 基本数据处理函数round()、int()、floor()、ceil()

    前言 对每位程序员来说,在编程过程中数据处理是不可避免的,很多时候都需要根据需求把获取到的数据进行处理,取整则是最基本的数据处理.取整的方式则包括向下取整.四舍五入.向上取整等等.下面就来看看在Pyt ...

  8. 本地Markdown文件上传到博客

    本地Markdown文件上传到博客 参考:https://www.cnblogs.com/ccylhw/p/13954153.html 1.Typora 最漂亮的写作APPhttps://www.ty ...

  9. 'Specifying a namespace in include() without providing an app_name '报错解决

    需要在每个ap下面的url.py 加入一个指定app的名字 比如  user  app  下的 url.py  文件加入: urlpatterns = []app_name = "user& ...

  10. djang2.1教育平台02

    在次申明,之所以重做这个资料是因为原幕课教程漏洞太多,新手根本没有办法正常照些学习,我凭着老男孩python 课程基础,重做这个教程 ,更改版本为当前最新版本,为了方法以后的人学习,并不是照着原文照  ...