[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再次被魔王抓走了(搞不懂他咋这么讨魔王 ...
随机推荐
- 第3章 探索性数据分析(单因子&对比)与可视化
1.理论铺垫 Dataframe和Series均适用 ~集中趋势:均值mean().中位数median().与分位数quantile(q=0.25).众数mode() ~离中趋势:标准差std().方 ...
- 使用FreeSurfer进行脑区分割
FreeSurfer 是美国哈佛-麻省理工卫生科学与技术部和马萨诸塞州总医院共同开发的一款磁共振数据处理软件包,是基于 Linux 平台的全免费开源软件.FreeSurfer 能完成对高分辨率的 MR ...
- 9 16 模拟赛&关于线段树上二分总结
1 考试时又犯了一个致命的错误,没有去思考T2的正解而是去简单的推了一下式子开始了漫漫找规律之路,不应该这样做的 为了得到规律虽然也打了暴力 但是还是打了一些不必要的程序 例如求组合数什么的比较浪费时 ...
- 关于c/c++中的二维数组与指针
设a是一个一维数组的数组名,则a表示其第一个元素的地址(即&a[0]),而&a表示整个数组的地址!尽管两者值相同(&a[0]==&a),因此&a是地址,*(&a ...
- 2017面向对象程序设计(Java)第十七周助教工作总结
本学期已接近尾声,java课程也即将结束.经过一学期的java学习,相信大家已经从最初的懵懂.困惑渐渐的走向了柳暗花明,并对java的体系结构有了更加清晰的认识.但一学期的学习是远远不 ...
- Jmeter(十九) - 从入门到精通 - JMeter监听器 -上篇(详解教程)
1.简介 监听器用来监听及显示JMeter取样器测试结果,能够以树.表及图形形式显示测试结果,也可以以文件方式保存测试结果,JMeter测试结果文件格式多样,比如XML格式.CSV格式.默认情况下,测 ...
- 可读流 - nodejs stream总结
可读流 包含的事件:data,readable,end,close ,error,pause,resume 常用方法:resume,read,pipe,pause 客户端的 HTTP 响应 服务器的 ...
- OS实现流程草稿
实现一个OS需要现在网上搜索 不要在Windows环境下写 nasm等汇编编译器的语法 bois中断函数使用 内存分布 描述符 实模式与保护模式 从实模式到保护模式比较难,可以从网上找一些代码能运行自 ...
- 14、Java文件操作stream、File、IO
1.文件操作涉及到的基本概念 File File类 是文件操作的主要对象中文意义就是 文件 顾名思意 万物皆文件,在计算上看到的所有东西都是文件保存,不管是你的图片.视频.数据库数据等等都是按照基本的 ...
- 怎么将PPT文件上传到微信公众号上?
我们都知道创建一个微信公众号,在公众号中发布一些文章是非常简单的,但公众号添加附件下载的功能却被限制,如今可以使用小程序“微附件”进行在公众号中添加附件. 以下是公众号添加附件使用“微附件”小程序的教 ...