【XSY2692】杨柳 - 网络流
题目来源:2018冬令营模拟测试赛(十)


题解:
继续鬼畜网络流……
首先这题有个显然的做法:bfs预处理出每个起点到每个终点的最短步数,然后直接建边加超级源汇跑费用流即可;
但是这样边数是$n^2$的,时间复杂度正好能过但是很卡常,要写EK才能过;
显然我是不会EK的,所以有一种更优秀的建图方法:
直接在原图点上建边,如果两个点能一步走到就连费用为1,流量为inf的边,建超级源建费用为0,流量为1的边连向所有起点,所有终点同样连向超级汇,直接跑费用流即可……
正确性显然,但是我不是很理解为什么这样会更快……
顺便学习了一波zkw费用流(多路增广是什么?不存在的)
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define inf 2147483647
#define eps 1e-9
#define get(x,y) ((x-1)*n+y)
using namespace std;
typedef long long ll;
struct edge{
int v,w,z,next;
}a[];
int way[][];
int n,m,N,aa,b,x,y,cnt=,vs,vt,tot=,tt=,cst=,flow=,ans=,head[],nm[][];
char mp[][];
bool vis[];
void add(int u,int v,int w,int z){
a[++tot].v=v;
a[tot].w=w;
a[tot].z=z;
a[tot].next=head[u];
head[u]=tot;
a[++tot].v=u;
a[tot].w=;
a[tot].z=-z;
a[tot].next=head[v];
head[v]=tot;
}
int aug(int u,int x){
if(u==vt){
ans+=cst*x;
return x;
}
int mxf=x;
vis[u]=true;
for(int tmp=head[u];tmp!=-;tmp=a[tmp].next){
int v=a[tmp].v;
if(a[tmp].w&&!a[tmp].z&&!vis[v]){
int f=aug(v,min(x,a[tmp].w));
a[tmp].w-=f;
a[tmp^].w+=f;
mxf-=f;
if(!mxf)return x;
}
}
return x-mxf;
}
bool lab(){
int mi=inf;
for(int i=vs;i<=vt;i++){
if(vis[i]){
for(int tmp=head[i];tmp!=-;tmp=a[tmp].next){
int v=a[tmp].v;
if(a[tmp].w&&!vis[v]){
mi=min(mi,a[tmp].z);
}
}
}
}
if(mi==inf)return false;
for(int i=vs;i<=vt;i++){
if(vis[i]){
for(int tmp=head[i];tmp!=-;tmp=a[tmp].next){
a[tmp].z-=mi;
a[tmp^].z+=mi;
}
}
}
cst+=mi;
return true;
}
int main(){
memset(head,-,sizeof(head));
scanf("%d%d%d%d%d",&n,&m,&N,&aa,&b);
vs=,vt=n*m+;
way[][]=aa,way[][]=b;
way[][]=aa,way[][]=-b;
way[][]=-aa,way[][]=b;
way[][]=-aa,way[][]=-b;
way[][]=b,way[][]=aa;
way[][]=b,way[][]=-aa;
way[][]=-b,way[][]=aa;
way[][]=-b,way[][]=-aa;
for(int i=;i<=n;i++){
scanf("%s",mp[i]+);
for(int j=;j<=m;j++)nm[i][j]=++cnt;
}
for(int i=;i<=N;i++){
scanf("%d%d",&x,&y);
add(vs,nm[x][y],,);
}
for(int i=;i<=N;i++){
scanf("%d%d",&x,&y);
add(nm[x][y],vt,,);
}
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
if(mp[i][j]=='.'){
for(int k=;k<;k++){
int ii=i+way[k][],jj=j+way[k][];
if(ii&&jj&&ii<=n&&jj<=m&&mp[ii][jj]=='.')add(nm[i][j],nm[ii][jj],inf,);
}
}
}
}
do{
do{
flow+=tt;
memset(vis,,sizeof(vis));
}while(tt=aug(vs,inf));
}while(lab());
printf("%d",flow<N?-:ans);
return ;
}
【XSY2692】杨柳 - 网络流的更多相关文章
- plain framework 1 网络流 缓存数据详解
网络流是什么?为什么网络流中需要存在缓存数据?为什么PF中要采用缓存网络数据的机制?带着这几个疑问,让我们好好详细的了解一下在网络数据交互中我们容易忽视以及薄弱的一块.该部分为PF现有的网络流模型,但 ...
- 网络流模板 NetworkFlow
身边的小伙伴们都在愉快地刷网络流,我也来写一发模板好了. Network Flow - Maximum Flow Time Limit : 1 sec, Memory Limit : 65536 KB ...
- COGS732. [网络流24题] 试题库
«问题描述:假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取m 道题组成试卷.并要求试卷包含指定类型的试题.试设计一个满足要求的组卷算法.«编程任务: ...
- ACM/ICPC 之 有流量上下界的网络流-Dinic(可做模板)(POJ2396)
//有流量上下界的网络流 //Time:47Ms Memory:1788K #include<iostream> #include<cstring> #include<c ...
- BZOJ 3144 [Hnoi2013]切糕 ——网络流
[题目分析] 网络流好题! 从割的方面来考虑问题往往会得到简化. 当割掉i,j,k时,必定附近的要割在k-D到k+D上. 所以只需要建两条inf的边来强制,如果割不掉强制范围内的时候,原来的边一定会换 ...
- bzoj3572又TM是网络流
= =我承认我写网络流写疯了 = =我承认前面几篇博文都是扯淡,我写的是垃圾dinic(根本不叫dinic) = =我承认这道题我调了半天 = =我承认我这道题一开始是T的,后来换上真正的dinic才 ...
- hdu3549还是网络流
最后一次训练模板(比较熟练了) 接下来训练网络流的建图 #include <cstdio> #define INF 2147483647 int n,m,ans,x,y,z,M,h,t,T ...
- 二分图&网络流&最小割等问题的总结
二分图基础: 最大匹配:匈牙利算法 最小点覆盖=最大匹配 最小边覆盖=总节点数-最大匹配 最大独立集=点数-最大匹配 网络流: 技巧: 1.拆点为边,即一个点有限制,可将其转化为边 BZOJ1066, ...
- COGS743. [网络流24题] 最长k可重区间集
743. [网络流24题] 最长k可重区间集 ★★★ 输入文件:interv.in 输出文件:interv.out 简单对比时间限制:1 s 内存限制:128 MB «问题描述: «编 ...
随机推荐
- sklearn学习1----sklearn.SVM.SVC
1.SVM有两种作用:分类和回归,分类是用SVC,回归用SVR. 2.SVC:(中文官网) 重点在svm.SVC(),fit(X,Y),以及SVC中的参数. 3.SVC参数: ①C,C是控制软间隔中的 ...
- JAVA中各个包的主要作用
00:48:0800:48:1022013013-06-282013-06-2800:48:182013-06-2800:48:20 java.util是JAVA的utility工具包 java.l ...
- win10 1809磁盘占用总是100%
快过年了,提前请假回家,装几台电脑公司备用.有个电脑装完系统开机很慢,开机完成之后电脑响应也很慢,于是打开任务管理器发现磁盘中用率一直是100%,然而程序读取数据的速度并不高. 解决思路: 关闭win ...
- 马上着手开发ios应用程序
https://developer.apple.com/library/ios/referencelibrary/GettingStarted/RoadMapiOSCh/chapters/Introd ...
- Python半双工聊天
半双工聊天 半双工聊天.创建一个简单的半双工聊天程序.指定半双工,我们的意思就是,当建立一个连接且服务开始后,只有一个人能打字,而另一个参与者在得到输入消息提示之前必须等待消息.并且,一旦发送者发送了 ...
- struts配置问题
- Apache 做反向代理服务器
apache做反向代理服务器 apache代理分为正向代理和反向代理: 1 正向代理: 客户端无法直接访问外部的web,需要在客户端所在的网络内架设一台代理服务器,客户端通过代理服务器访问外部的web ...
- 压力工具代码及epoll使用
服务器编程 P347的压力工具代码不错,对于epoll用的好,可以看.
- js面向对象编程: js类定义函数时prototype和this差别?
在面向对象编写js脚本时,定义实例方法主要有两种 例如以下: function ListCommon2(afirst) { var first=afirst; this.do1=function () ...
- TeamTalk Android代码分析(业务流程篇)---消息发送和接收的整体逻辑说明
第一次纪录东西,也没有特别的顺序,想到哪里就随手画了一下,后续会继续整理- 6.2消息页面动作流程 6.2.1 消息页面初始化的总体思路 1.页面数据的填充更新直接由页面主线程从本地数据库请求 2.数 ...