[BZOJ4449][Neerc2015][分治][最短路]Distance on Triangulation

[ZJOI2016]旅行者(网格图分治最短路) 请别什么最后都可以概括成——套路。这世界太多套路我还是像个小孩。 阅读详情
题意

给定一个凸n边形,以及它的三角剖分。再给定q个询问,每个询问是一对凸多边行上的顶点(a,b),问点a最少经过多少条边(可以是多边形上的边,也可以是剖分上的边)可以到达点b。


这道题刚了3个小时啊
然而因为一句swap没打只有45分……

类似于zjoi2016的旅行者

对于当前的图,找到一条边能够把图分成左右两半,比如图中2-5这条边
这里写图片描述

对于询问(x,y),若x在这条边的左边,y在这条边的右边,那么这个询问的最短路程一定经过这条边的两个端点之一,用spfa求出这条边两个端点到当前图的每个点的最短路径,然后就可以求出这样跨过这条的询问的答案。然后递归处理左右两半,复杂度O(nlogn)

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
#include <ctime>
#include <string>
#define N 200010

using namespace std;

pair<int,int> nq[N];
int n,m,u,v,cnt,g,ng;
struct stp{
  int l,r,g;
}A[N<<2],Q[N<<2],tmp1[N<<2],tmp2[N<<2];
struct edge{
  int t,nx;
}E[N<<2];
int B[N*100],Ans[N],G[N],dis1[N],dis2[N],vis[N],tmp3[N*100],tmp4[N*100];
queue<int> q;

inline void reaD(int &x){
  char c=getchar(); x=0;
  for(;c<48||c>57;c=getchar());for(;c>=48&&c<=57;x=x*10+c-48,c=getchar());
}

inline int check(int l,int r,int x){
  int mid,Ans;
  while(l<r) B[mid=l+r>>1]>=x?r=mid:l=mid+1;
  return r;
}

inline void spfa(int x,int l,int r,int *dis){
  for(int i=l;i<=r;i++) dis[B[i]]=1<<30,vis[B[i]]=0;
  vis[x]=1; dis[x]=0;
  q.push(x); 
  while(!q.empty()){
    int u=q.front(); vis[u]=0; q.pop();
    for(int i=G[u];i;i=E[i].nx)
      if(dis[u]+1<dis[E[i].t]&&B[check(l,r,E[i].t)]==E[i].t){
    dis[E[i].t]=dis[u]+1;
    if(!vis[E[i].t]){
      q.push(E[i].t);
      vis[E[i].t]=1;
      if(dis[q.front()]>dis[q.back()]) swap(q.front(),q.back());
    }
      }
  }
}

inline void Insert(int x,int y){
  E[++cnt].t=y; E[cnt].nx=G[x]; G[x]=cnt;
  E[++cnt].t=x; E[cnt].nx=G[y]; G[y]=cnt;
}

inline int GetAns(int x,int y){
  int Ans1=min(dis1[x]+dis1[y],dis1[x]+dis2[y]+1),
    Ans2=min(dis2[x]+dis1[y]+1,dis2[x]+dis2[y]);
  return min(Ans1,Ans2);
}

void solve(int l,int r,int x,int y,int a,int b){
  if(a>b) return;
  int Min=1<<30,w;
  for(int i=l;i<=r;i++){
    int pp=check(x,y,A[i].l),qq=check(x,y,A[i].r);
    if(pp<qq) swap(qq,pp);
    if(max(pp-qq+1,y-x+1-pp+qq)<Min) Min=max(pp-qq+1,y-x+1-pp+qq),w=i;
  }
  if(A[w].l>A[w].r) swap(A[w].l,A[w].r);
  spfa(A[w].l,x,y,dis1); spfa(A[w].r,x,y,dis2);

  int k1=0,k2=0,k3=0,k4=0,k5=0,k6=0;
  for(int i=a;i<=b;i++){
    if((Q[i].l==A[w].l&&Q[i].r==A[w].r)||(Q[i].r==A[w].l&&Q[i].l==A[w].r)){
      Ans[Q[i].g]=1; continue;
    }
    Ans[Q[i].g]=min(Ans[Q[i].g],GetAns(Q[i].l,Q[i].r));
    if(Q[i].l>A[w].l&&Q[i].l<A[w].r&&Q[i].r>A[w].l&&Q[i].r<A[w].r) tmp1[++k1]=Q[i];
    if((Q[i].r<A[w].l||Q[i].r>A[w].r)&&(Q[i].l<A[w].l||Q[i].l>A[w].r)) tmp2[++k2]=Q[i];
  }
  for(int i=1;i<=k1;i++) Q[a+i-1]=tmp1[i];
  for(int i=1;i<=k2;i++) Q[a+k1+i-1]=tmp2[i];
  for(int i=x;i<=y;i++){
    if(B[i]>=A[w].l&&B[i]<=A[w].r) tmp3[++k3]=B[i];
    if(B[i]<=A[w].l||B[i]>=A[w].r) tmp4[++k4]=B[i];
  }
  for(int i=1;i<=k3;i++) B[x+i-1]=tmp3[i];
  for(int i=1;i<=k4;i++) B[x+k3+i-1]=tmp4[i];
  for(int i=l;i<=r;i++)
    if(i!=w)
      if(A[i].l>=A[w].l&&A[i].r<=A[w].r) tmp1[++k5]=A[i];
      else tmp2[++k6]=A[i];
  for(int i=1;i<=k5;i++) A[l+i-1]=tmp1[i];
  for(int i=1;i<=k6;i++) A[l+k5+i-1]=tmp2[i];

  solve(l+k5,l+k5+k6-1,x+k3,x+k3+k4-1,a+k1,a+k1+k2-1);
  solve(l,l+k5-1,x,x+k3-1,a,a+k1-1);
}

int main(){
  freopen("drive.in","r",stdin);
  freopen("drive.out","w",stdout);
  reaD(n);
  for(int i=1;i<=n-3;i++){
    reaD(A[i].l),reaD(A[i].r),Insert(A[i].l,A[i].r);
    if(A[i].l>A[i].r) swap(A[i].r,A[i].l);//……
  }
  for(int i=1;i<=n;i++) B[i]=i;
  reaD(m);
  for(int i=1;i<=m;i++){
    reaD(Q[i].l);reaD(Q[i].r); Q[i].g=i;
    nq[i].first=Q[i].l; nq[i].second=Q[i].r;
    if(Q[i].l%n+1==Q[i].r||Q[i].r%n+1==Q[i].l) Ans[i]=1;
    else if(Q[i].l==Q[i].r) Ans[i]=0;
    else Q[++g]=Q[i];
  }
  for(int i=1;i<=n;i++) Insert(i,i%n+1);
  for(int i=1;i<=m;i++) Ans[i]=1<<30;
  solve(1,n-3,1,n,1,g);
  for(int i=1;i<=m;i++)
    if(Ans[i]!=(1<<30)) printf("%d\n",Ans[i]);
    else{
      if(nq[i].first>nq[i].second) swap(nq[i].first,nq[i].second);
      printf("%d\n",min(nq[i].second-nq[i].first,nq[i].first+n-nq[i].second));
    }
  return 0;
}

听说有点分治的做法,打起来简单多了……

NEERC2015 editorial 立即下载

相关推荐

NVIDIA Tao Toolkit环境配置踩坑

请搭配食用该文章为 Tao 安装中可能出现的问题进行解答,如果存在本文章中没出现的问题,欢迎提问,由我复现后更新文章。由于大部分云服务器厂商不能支持 docker,因此我使用的环境为2023年5月27日在平台租的 3080 旧版环境进行实验。

qq_36630208的博客 771

bzoj4449 [Neerc2015]Distance on Triangulation

4449: [Neerc2015]Distance on Triangulation Time Limit:100 SecMemory Limit:512 MBSubmit:205Solved:69[Submit][Status][Discuss] Description 给定一个凸n边形,以及它的三角剖分。再给定q个询问,每个询问是一对凸多边行上的顶点(a...

weixin_30252709的博客 147

使用 DeepSeek 配合 即梦AI 生成视频的详细教程

访问即梦AI官网,选择“AI作图”功能,将DeepSeek生成的提示词逐条粘贴至输入框,选择适配的模型(如“通用XL Pro”)和参数(如画幅比例、风格强度)1113。“我要制作一个关于普洱茶文化的宣传视频,请设计一个30秒的脚本,包含时间轴、画面描述、文案和分镜提示词,以表格形式输出。:云南古茶树群,清晨薄雾,金色晨光,露珠特写,国风山水画质感,16:9画幅,使用Nikon D850参数模拟513。:结合DeepSeek生成的知识点脚本与即梦AI的插画风格,制作科普动画211。

weixin_48995695的博客 3万+

【分治+最短路】UOJ#184【ZJOI2016】旅行者

原题地址 【题目大意】 有n条横向道路,m条纵向道路,形成了一些交点。相邻两个交点之间道路长为wij,现在给出q个询问,每次询问两个交点之间的最短路径。 n×m≤2×104,q≤105n×m≤2×104,q≤105n\times m \le 2\times 10^4,q\le 10^5 【题目分析】 我已经嗅到了分治的气息。 当然也可能是分块。 (我更喜欢前者) 【解题思路】 看...

MEET YOU FIRST TIME 709

HUMAnN数据库国内备份下载源(转自刘永鑫博士github)

百度云链接 R语言常用包合集 Windows 10版4.0.x:链接:https://pan.baidu.com/s/1JFwLP2SonK1howD5MNgNYg 提取码:l08k Windows 10版3.6.x:链接:https://pan.baidu.com/s/1h-qR2lmlaMgR4M7VbgtAFg 提取码:s5fi 下载后解压至当前目录,可获得3.6/4.0目录,剪切并替换文档 - R - win-library - 3.6/4.0 目录即可 扩增子数据库 宏基因组数据库 HUM.

zlabx的博客 3242

Zemax单模光纤耦合仿真避坑指南:数值孔径、模式匹配与镀膜影响详解

本文详细解析了Zemax单模光纤耦合仿真中的关键避坑要点,包括数值孔径的多重定义与换算、模式匹配度评估及镀膜影响分析。通过实际案例和技术公式,帮助工程师避免常见仿真误差,提升激光通信和光纤传感系统的设计精度。特别针对OpticStudio用户提供了实用的参数设置建议和优化策略。

weixin_30836759的博客 465

bzoj4449: [Neerc2015]Distance on 点分治 三角剖分 平面图与对偶图

bzoj4449: [Neerc2015]Distance on Triangulation Description 给定一个凸n边形,以及它的三角剖分。再给定q个询问,每个询问是一对凸多边行上的顶点(a,b),问点a最少经过多少条边(可以是多边形上的边,也可以是剖分上的边)可以到达点b。 Input** 第一行一个整数n(n &amp;lt;= 50000),代表有n个点。点1,2,3,…,n是凸多边形...

maxtir的博客 818

ESP32、MicroPython、天问ASR-PRO,串口发送数据并播报

天问ASRPRO语音芯片内置脑神经网络处理器,支持DNN、TDNN、RNN等神经网络及卷积运算硬件运算,非软件运算,支持语音识别、声纹识别、语音增强、语音检测、单麦克风降噪增强、单麦克风回声消除、360度全方位拾音等功能。ASR-PRO可以图形化编程,降低开发难度,对小白友好。之前使用ASRPRO与ESP32进行过语音控制,这次由于一个项目需要对ESP处理过后的数据进行播报,就想到利用该模块。以下程序主要为测试代码,并非实际项目,仅供参考学习(若有错误,欢迎指正)。二者通过串口通信,波特率为9600。

weak_student的博客 5951

[NEERC 2015] bzoj4449 Distance on Triangulation [分治+最短路]

Description: 给定一个凸nnn边形,以及它的三角剖分。再给定qqq个询问,每个询问是一对凸多边行上的顶点(a,b)(a,b)(a,b),问点aaa最少经过多少条边(可以是多边形上的边,也可以是剖分上的边)可以到达点bbb。 Solution: 看起来很难写,其实想清楚还是比较好写的。 我们可以对每个多边形进行分治,每次选择其中的一个分的最均匀的对角线,以其两个顶点做最短路,...

pocket_legend 478

Qt Creator 下载和安装

在线安装程序是一个小型的安装程序,它将在您的计算机上下载和安装 Qt Creator。离线安装程序是一个较大的安装包,您可以将其保存在本地,并在没有网络连接的情况下安装 Qt Creator。在 Qt 官方网站上,您可以找到 Qt Creator 的下载页面。Qt Creator 是一款跨平台的集成开发环境(IDE),用于开发基于 Qt 框架的应用程序。在这一步中,您可以选择是否安装 Qt Creator 的附加组件。一旦您完成了组件的选择,安装程序将开始将 Qt Creator 安装到您的计算机上。

HackLogic的博客 6821

Python - 多页pdf 合称为一页

尝试使用 ReportLab 来重画 pdf,但探索起来有点麻烦。重要的是解决手头这个问题,所以就算方法蠢,但简单完事。以下生成结果,最有一页 pdf 可能会显示在第一页,手动编辑下 pdf 即可;或者你也可以修改代码逻辑来完善。打印ppt,一页占用A4纸比较浪费,想多页合成一个 A4大小;安装 fitz,单独安装 fitz 使用可能会报错。将 PDF 拆分为 图片来保存。

AI工程化、开源分享、文档翻译、代码笔记 1425

[点分治 离线] BZOJ 4449 [Neerc2015]Distance on Triangulation

其实简单的找一条边然后分成两半 被我硬生生写成对偶图点分治分成三块 233 就把所有询问一起处理 点分治时 如果两个点在同一侧 就递归 否则对三个点bfs就能知道最短路径#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<map> #include<vector> #define c

雯舞 805

服务部署之配置WSUS更新服务(基于Windows配置 Server 2022)

服务部署之配置WSUS更新服务(基于Windows配置 Server 2022)

2301_77192876的博客 2214

BZOJ4449: [Neerc2015]Distance on Triangulation

$n \leq 50000$的凸多边形,给一个三角剖分,$q \leq 100000$组询问每次问两点之间最短路。 凸多边形是个特殊的图,一般图找单源最短路已经有精美的算法了。然而多组询问呢? 其实关于路径统计、路径询问的问题,在树上常用的是点分治,每次能统计经过根节点的路径,然后再尽量把他分成较大值较小的两块。在这里可以采用同样的方法。 一:凸多边形三角剖分的对偶图是一棵树,直接...

weixin_30815469的博客 84

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

【bzoj 4449】[Neerc2015]Distance on Triangulation

Description 给定一个凸n边形,以及它的三角剖分。再给定q个询问,每个询问是一对凸多边行上的顶点(a,b),问点a最少经过多少条边(可以是多边形上的边,也可以是剖分上的边)可以到达点b。 Input 第一行一个整数n(n <= 50000),代表有n个点。点1,2,3,…,n是凸多边形上是顺时针排布的。 接下来n-3行,每行两个整数(x,y),代表(x,y)之间...

weixin_30916125的博客 164

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

BZOJ4449 : [Neerc2015]Distance on Triangulation

首先拓扑,每次取出度数为$2$的点,这样可以把所有三角形都找到。 那么建出对偶图,会发现是一棵树。 对这棵树进行点分治,每次取出重心,DFS求出所有在里面的点,然后从重心$3$个点分别做一次BFS。 对于每个询问,如果不经过重心这个区域,那么递归求解,否则用BFS的结果回答即可。 时间复杂度$O(n\log n)$。   #include&lt;cstdio&gt; #inclu...

weixin_34258838的博客 147

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

模拟赛20200213【增量求第n小,三角剖分分治最短路,树上路径中位数之和】

T1: n≤6500n\le6500n≤6500 题解: 因为10i+1/2i&1=010^{i+1}/2^i\&1=010i+1/2i&1=0, 10i/2i&1=110^i/2^i\&1=110i/2i&1=1,所以10k10^k10k的二进制表示的末尾一定有kkk个0 所以可以记录长度为lenlenlen的所有合法串及其对应的二进制表示,...

Master.Yi的博客 366

【分治+最短路+BIT】CC_QGRID Querying on a Grid

【题目】 Codechef 一个m×nm\times nm×n的网格图,每条边有权,有QQQ次操作: 给出(i1,j1,i2,j2,c)(i_1,j_1,i_2,j_2,c)(i1​,j1​,i2​,j2​,c),将(i1,j1)(i_1,j_1)(i1​,j1​)到(i2,j2)(i_2,j_2)(i2​,j2​)最短路上的所有点加上点权ccc 询问点(i,j)(i,j)(i,j)的点权。 m...

MEET YOU FIRST TIME 452

洛谷 P6974 [NEERC2015] Adjustment Office 题解

其中 4−2 的 2 是删除行的数量,1+3 是删除的行编号之和,这个可以在删除时顺便保存。发现了吗,每一列的和就是从 1 加到 n 的和再加上 n 倍的 x(第 x 列)。以下是引用:有一个大小为 n×n 的矩阵,每个位置的值为该位置的行数 + 列数。这个时候答案就应该是 (1+4)×4÷2+2×(4−2)−(1+3)。有一个大小为 n×n 的矩阵,每个位置的值为该位置的行数+列数。其中 cc 是删除行的数量,c_sum 即删除行(编号)之和。其中 s 就是事先算好的 (1+n)×n÷2。

2202_75696835的博客 238

省选模拟赛20200213 T2 开开车(多边形三角剖分图分治求最短路)

题解 直接分治啊啊啊啊啊啊啊啊!!!!!!!!!! 找一条对角线,把两边的点数尽量分的均匀 然后在这个图中用bfs求出这条对角线两个端点到其它所有点的距离 一次是O(n)的(注意对角线是不会交叉的,所以在左右两个部分的点想要到达对方,就必定会经过中间的分割边的端点,如果走到分治的区域之外,它一定会浪费步数) 由于n的规模在分治中不断减小,分治层数是logn的,所...

crosnken的博客 371

西安十五日游day10 分治

CodeForces 484E Sign on Fence UVALive 7469 Distance on Triangulation HDU 4812 D Tree CodeForces 97B Superset OpenJ_POJ C15C Rabbits Festival HDU 5721 Palace HDU 5755 Gambler BoCodeForces 484E Sign on F

nike0good |Oier&ACMer | 熟能生巧 804

NEERC15

2015-2016 ACM-ICPC Northeastern European Regional Contest 再开一个新坑吧 目前姿势有限,C、H、I仍然处于弃坑状态 代码戳这里 Problem A. Adjustment Office 显然假设每一行都没有进行过删除的话,那么答案就-nx的和+nx(\(x\)为行号或者列号) 考虑进行过清零以后的问题,由于是整行整列的删除的 那么我...

weixin_30528371的博客 336

[ZJOI2006] 物流运输(最短路+dp)

物流公司要把一批货物从码头 A 运到码头 B。由于货物量比较大,需要n天才能运完。货物运输过程中一般要转停好几个码头。物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪。由于各种因素的存在,有的时候某个码头会无法装卸货物。这时候就必须修改运输路线,让货物能够按时到达目的地。但是修改路线是—件十分麻烦的事情,会带来额外的成本。因此物流公司希望能够订一个n天的运输计划,使得总成本尽可能地小。

m0_60738889的博客 2104

【BZOJ 4449】[Neerc2015]Distance on Triangulation 多边形分治结构

这题好神啊……正解方向是分治,据我所知的分治方法有:I.离线后直接对多边形以及所有的询问进行分治 II.建立多边形的分治结构(对于三角形来说类似线段树,对于对角线来说类似平衡树),然后每次在这个分治结构上进行查询 III.将原图转为其对偶图(利用拓扑),发现是一棵树,然后在这棵树上进行分治(似乎也有离线分治和在线建立分治结构两种方法)我用的是第二种方法,感觉写起来不是很容易,但是也并不恶心,具体实...

weixin_30345055的博客 151

Gym 100851 Distance on Triangulation

题意:给你一个N边形, 然后这个n边形有n-3条边,然后询问2点之间的最短路。 题解:分治。 我们可以找到一条边,使得这幅图能分成大小相同的2幅图,那么我们就可以确定那些被分割开的询问的答案是多少了。 我们假定u v是分开的, 然后我们从u点bfs一遍现在的图,v点bfs一遍现在的图,确定所有点离这2个点的位置,对于切断的询问更新答案。 需要注意的就是,每次都一定要重新建图,免得...

dengpangbu3703的博客 240
上一篇: [BZOJ4316][仙人掌][DP]小C的独立集
下一篇: WC2017 && THUWC2017 游记
LowestJN
博客等级 码龄10年 76粉丝 422原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值