【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 «问题描述: «编 ...
随机推荐
- alg--分治法
分治--分而治之, 把大的问题分成n个小的问题,分别处理,然后汇总小问题的结果. 具体介绍可以参考这位大哥的blog: https://www.cnblogs.com/steven_oyj/archi ...
- Eclipse设置jdk相关
2.window->preferences->java->Compiler->设置右侧的Compiler compliance level 3.window->prefe ...
- 通过setSystemUiVisibility实现状态栏跟Activity之间的位置关系
曾经说到去除状态栏和标题栏总会用到动态代码的方式实现: getWindow().setFlags(WindowManager.LayoutParams. FLAG_FULLSCREEN , Windo ...
- c6----函数的声明和实现
// // main.c // 函数的声明和定义 // // Created by xiaomage on 15/6/7. // Copyright (c) 2015年 xiaomage. All r ...
- iOS 权限判断 跳转对应设置界面
相机权限 1.1 使用说明 在合适的地方导入#import <AVFoundation/AVFoundation.h> 使用AVAuthorizationStatus类获取当前权限状态 在 ...
- python中数字的排序
lst = [2,22,4,7,18]for j in range(len(lst)): #记录内部排序的次数 i = 0 while i < len(lst)-1: if lst[i] > ...
- POJ 1384 Piggy-Bank DP
一个完全背包 很裸,对于我这种DP渣渣都能1A.. // by SiriusRen #include <cstdio> #include <cstring> #include ...
- P2216 [HAOI2007]理想的正方形(二维RMQ)
题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: 第一行为3个整数,分别表示a,b,n的值 第二行至 ...
- 查看md文件
使用命令将md文件转为html,在浏览器中演示 通过npm安装i5ting_toc 安装好node之后,可以直接使用npm.Windows+R打开运行框,输入cmd,打开命令窗口.连网的情况下,输入如 ...
- vue路由钩子拦截器beforeEach和afterEach及页面路由变化路由监听
在路由跳转的时候,我们需要一些权限判断或者其他操作.这个时候就需要使用路由的钩子函数. 定义:路由钩子主要是给使用者在路由发生变化时进行一些特殊的处理而定义的函数. 总体来讲vue里面提供了三大类钩子 ...