[FJOI2020]世纪大逃亡 题解
FJOI2020 D1T1
题目大意
给出一个由 $n$ 行 $m$ 列的点构成的网格,其中第 $1$ 行,第 $n$ 行,第 $1$ 列与第 $m$ 列为边界,给出 $s$ 个点,求这 $s$ 个点到边界的最小的路径长度之和,要求路径不能交叉。 $n*m\leq20000$。
思路分析
可以看出这是个费用流模板题。根据实测,本题数据卡 EK 单路增广,只能拿到 $70$ 分,需要多路增广才能过。虽然多路增广理论复杂度相同,但是本题中每次增广只能增加 $1$ 的流量,多路增广的确可以提高一定的效率。
#include<iostream>
#include<cstdio>
#include<queue>
#define ano ((i-1)^1)+1
using namespace std;
const int N=1e6+100,INF=0x7f7f7f7f;
int n,m,S,tot,s,t,f,ans;
int head[N],ver[2*N],Next[2*N],edge[2*N],cost[2*N];
int minf[N],pre[N],d[N];
bool v[N];
void add(int x,int y,int z,int c)
{
ver[++tot]=y,edge[tot]=z,cost[tot]=c,Next[tot]=head[x],head[x]=tot;
ver[++tot]=x,edge[tot]=0,cost[tot]=-c,Next[tot]=head[y],head[y]=tot;
}
bool spfa()
{
for(int i=0;i<=t;i++)
d[i]=INF,v[i]=0;
queue<int> q;
q.push(s);
v[s]=1,d[s]=0,minf[s]=INF;
while(q.size())
{
int x=q.front();q.pop();v[x]=0;
for(int i=head[x];i;i=Next[i])
{
if(!edge[i])
continue;
int y=ver[i];
if(d[x]+cost[i]<d[y])
{
d[y]=d[x]+cost[i];
minf[y]=min(minf[x],edge[i]);
pre[y]=i;
if(!v[y])
{
v[y]=1;
q.push(y);
}
}
}
}
return d[t]!=INF;
}/*
void update()
{
int x=t;
while(x!=s)
{
int i=pre[x];
edge[i]-=minf[t];
edge[ano]+=minf[t];
x=ver[ano];
}
f+=minf[t];
ans+=d[t]*minf[t];
}*///单路增广
int dinic(int x,int flow)
{
if(x==t)
return flow;
v[x]=1;
int rest=flow,use;
for(int i=head[x];i && rest;i=Next[i])
{
int y=ver[i];
if(v[y] || !edge[i] || d[y]!=d[x]+cost[i])
continue;
use=dinic(y,min(rest,edge[i]));
if(!use)
d[y]=0;
edge[i]-=use,edge[ano]+=use,rest-=use;
ans+=cost[i]*use;
}
return flow-rest;
}
int id(int x,int y,int z)
{
return (x-1)*m+y+z*n*m;
}
void clear()
{
t=2*n*m+1,ans=tot=f=0;
for(int i=0;i<=t;i++)
head[i]=pre[i]=minf[i]=0;
}
int main()
{
//freopen("covid.in", "r", stdin);
//freopen("covid.out", "w", stdout);
while(scanf("%d%d%d",&n,&m,&S)!=EOF)
{
clear();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
add(id(i,j,0),id(i,j,1),1,0);
if(i!=1)
add(id(i,j,1),id(i-1,j,0),1,1);
if(i!=n)
add(id(i,j,1),id(i+1,j,0),1,1);
if(j!=1)
add(id(i,j,1),id(i,j-1,0),1,1);
if(j!=m)
add(id(i,j,1),id(i,j+1,0),1,1);
if(i==1 || i==n || j==1 || j==m)
add(id(i,j,1),t,1,0);
}
for(int i=1,x,y;i<=S;i++)
{
scanf("%d%d",&x,&y);
add(s,id(x,y,0),1,0);
}/*
while(spfa())
update();*///单路增广
while(spfa())
{
int flow;
do{
for(int i=0;i<=t;i++)
v[i]=0;
flow=dinic(s,INF);
f+=flow;
}while(flow);
}
if(f==S)
printf("%d\n",ans);
else
puts("-1");
}
return 0;
}
[FJOI2020]世纪大逃亡 题解的更多相关文章
- HDU 1253 胜利大逃亡 题解
胜利大逃亡 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- Hdoj 1253.胜利大逃亡 题解
Problem Description Ignatius被魔王抓走了,有一天魔王出差去了,这可是Ignatius逃亡的好机会. 魔王住在一个城堡里,城堡是一个ABC的立方体,可以被表示成A个B*C的矩 ...
- hdoj 1253 胜利大逃亡
胜利大逃亡 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- 胜利大逃亡(续)(状态压缩bfs)
胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- 胜利大逃亡(续)(bfs+状态压缩)
胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- HDU 3533 Escape(大逃亡)
HDU 3533 Escape(大逃亡) /K (Java/Others) Problem Description - 题目描述 The students of the HEU are maneu ...
- hdu.1429.胜利大逃亡(续)(bfs + 0101011110)
胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- 胜利大逃亡[HDU1253]
胜利大逃亡 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- hdu 1429 胜利大逃亡(续)
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1429 胜利大逃亡(续) Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王 ...
随机推荐
- Python os.tcsetpgrp() 方法
概述 os.tcsetpgrp() 方法用于设置与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组为pg.高佣联盟 www.cgewang.com 语法 tcsetpgrp()方 ...
- PHP strspn() 函数
实例 返回在字符串 "Hello world!" 中包含字符 "kHlleo" 的数目: <?php高佣联盟 www.cgewang.comecho st ...
- ASP.NET MVC+LayUI视频上传
前言: 前段时间在使用APS.NET MVC+LayUI做视频上传功能的时,发现当上传一些内存比较大的视频就会提示上传失败,后来通过查阅相关资料发现.NET MVC框架为考虑安全问题,在运行时对请求的 ...
- explain关键字使用解释
原文: 58沈剑 架构师之路 https://mp.weixin.qq.com/s/oWNrLHwqM-0ObuYbuGj98A <数据库允许空值,往往是悲剧的开始>一文通过explai ...
- Sharding-JDBC实现水平拆分-单库分表
参考资料:猿天地 https://mp.weixin.qq.com/s/901rNhc4WhLCQ023zujRVQ 作者:尹吉欢 当单表的数量急剧上升,超过了1千万以上,这个时候就要对表进行水平 ...
- api接口返回动态的json格式?我太难了,尝试一下 linq to json
一:背景 1. 讲故事 前段时间和一家公司联调api接口的时候,发现一个奇葩的问题,它的api返回的json会动态改变,简化如下: {"Code":101,"Items& ...
- pycharm2020专业版永久激活
pycharm专业版激活 1. 下载pycharm(专业版) 注意:这里一定要去官网下载正版的专业版pycharm. pycharm官网 但是这是pycharm的最新版,目前激活教程仅适用以前的202 ...
- Android 布局的一些控件的补充和布局的补充(今儿没课)
前面写的博客可能会有点乱: 1,是不太会排版. 2,就是我一边看书,一边听学长讲课,所以有的知识就融入进去了,我写的都是自己的意见和理解,大家取我精华,弃我糟粕哈. 今天是书上的内容,主要讲布局的,一 ...
- Linux系统之《消息队列》入手应用
目录 简述 代码 编译 运行 简述 消息队列是Linux进程间通信方式之一,消息队列一般是用于简单的通信,数据量不大,通信不频繁的情况.如果交互频繁或者数据量大就不适合了. 代码 下面直接上代码,发送 ...
- 一个Python爬虫工程师学习养成记
大数据的时代,网络爬虫已经成为了获取数据的一个重要手段. 但要学习好爬虫并没有那么简单.首先知识点和方向实在是太多了,它关系到了计算机网络.编程基础.前端开发.后端开发.App 开发与逆向.网络安全. ...