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]世纪大逃亡 题解的更多相关文章

  1. HDU 1253 胜利大逃亡 题解

    胜利大逃亡 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  2. Hdoj 1253.胜利大逃亡 题解

    Problem Description Ignatius被魔王抓走了,有一天魔王出差去了,这可是Ignatius逃亡的好机会. 魔王住在一个城堡里,城堡是一个ABC的立方体,可以被表示成A个B*C的矩 ...

  3. hdoj 1253 胜利大逃亡

    胜利大逃亡 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  4. 胜利大逃亡(续)(状态压缩bfs)

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  5. 胜利大逃亡(续)(bfs+状态压缩)

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  6. HDU 3533 Escape(大逃亡)

    HDU 3533 Escape(大逃亡) /K (Java/Others)   Problem Description - 题目描述 The students of the HEU are maneu ...

  7. hdu.1429.胜利大逃亡(续)(bfs + 0101011110)

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  8. 胜利大逃亡[HDU1253]

    胜利大逃亡 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  9. hdu 1429 胜利大逃亡(续)

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1429 胜利大逃亡(续) Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王 ...

随机推荐

  1. 使用AOP获取自定义注解的内容

    目录结构: 一:自定义注解 package org.example.annotation; import java.lang.annotation.ElementType; import java.l ...

  2. 4-Pandas之数据类型与数据筛选

    一.数据类型 1.Pandas的数据类型主要结合了pandas和numpy两个模块中的数据类型,包括以下几种: float int bool datetime64[ns]------>日期类型 ...

  3. php getimagesize 函数 - 获取图像信息

    getimagesize() 函数用于获取图像大小及相关信息,成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息. 语法格式:高佣联盟 www.cgewang.co ...

  4. Calibre LVS BOX 详细用法

    https://www.cnblogs.com/yeungchie/ LVS BOX的使用对于后端的团队协作起到非常便利的作用. 通过在lvs rules file添加BOX的相关语句可以达到这个目的 ...

  5. pagehelper的使用和一些坑!

    [toc] ##1.1 pagehelper介绍和使用 PageHelper是一款好用的开源免费的Mybatis第三方物理分页插件. 原本以为分页插件,应该是很简单的,然而PageHelper比我想象 ...

  6. 2020牛客暑期多校训练营 第二场 A All with Pairs 字符串hash KMP

    LINK:All with Pairs 那天下午打这个东西的时候状态极差 推这个东西都推了1个多小时 (比赛是中午考试的我很困 没睡觉直接开肝果然不爽 一开始看错匹配的位置了 以为是\(1-l\)和\ ...

  7. C/C++编程笔记:C语言对齐问题【结构体、栈内存以及位域对齐】

    引言 考虑下面的结构体定义: 假设这个结构体的成员在内存中是紧凑排列的,且c1的起始地址是0,则s的地址就是1,c2的地址是3,i的地址是4. 现在,我们编写一个简单的程序: 运行后输出: 为什么会这 ...

  8. C语言中的数据转换和定义常量

    一.数据转换 1.数据类型转换:C 语言中如果一个表达式中含有不同类型的常量和变量,在计算时,会将它们自动转换为同一种类型:在 C 语言中也可以对数据类型进行强制转换: 2.自动转换规则: a)浮点数 ...

  9. Android Studio中如何使用自定义的framework库

    在安卓app开发中,通常不会遇到需要使用自定义framework库的情况,使用的都是标准的内核库.但也有例外,比如针对定制化的ROM,ROM厂商可能在ROM中对安卓源码做过修改,对应用层app暴露出与 ...

  10. 线性DP 学习笔记

    前言:线性DP是DP中最基础的.趁着这次复习认真学一下,打好基础. ------------------ 一·几点建议 1.明确状态的定义 比如:$f[i]$的意义是已经处理了前$i个元素,还是处理第 ...