*传送

给定平面上的n个点,定义$(x_1,y_1)$到$(x_2,y_2)$的费用为min(|$x_1$-$x_2$|,|$y_1$-$y_2$|),求从1号点走到n号点的最小费用。

先给一段证明:给定三个x值,$x_1<x_2<x_3$。可得$x_2-x_1<x_3-x_2<x_3-x_1$,对于最小费用,很明显只有$x_2-x_1$是有用的。对y同理,同时要注意我们不能把$x$和$y$两者混谈。由此我们得到了一个思路,分层图x和y跑一次最短路。

首先两个$cmp$函数对$n$个点进行的两次排序(注意在之前把点的序号也存下来):

 bool cmp1(node a,node b)
{
return a.x<b.x;
}
bool cmp2(node a,node b)
{
return a.y<b.y;
}

链式前向星构图:

 struct edge
{
int next,to,w;
}edge[maxn];
void add(int u,int v,int w)
{
edge[++tot].w=w;
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot;
}
sort(a+,a+n+,cmp1);
for (int i = ;i < n;i++)
{
add(a[i].id,a[i+].id,abs(a[i].x-a[i+].x));
add(a[i+].id,a[i].id,abs(a[i].x-a[i+].x));
}
sort(a+,a+n+,cmp2);
for (int i = ;i < n;i++)
{
add(a[i].id,a[i+].id,abs(a[i].y-a[i+].y));
add(a[i+].id,a[i].id,abs(a[i].y-a[i+].y));
}

然后是很标准的dij板子:

 void Dijkstra(int S)
{
q.push(make_pair(,S)); memset(vis,,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); dis[S] = ;
while(!q.empty())
{
int x = q.top().second;
q.pop();
if(vis[x])
continue;
vis[x] = ;
for(int i=head[x];i!=;i=edge[i].next)
{
int to1=edge[i].to;
if(dis[to1] > dis[x] + edge[i].w)
{
dis[to1] = dis[x] + edge[i].w ;
q.push(make_pair(-dis[to1],to1));
}
}
}
return;
}

完整代码如下:

 #include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
using namespace std;
#define ll long long
int n;
const int maxn=;
priority_queue< pair<int ,int > >q;
int dis[maxn],vis[maxn];
int tot=,head[maxn];
int read(){
int x=,a=;
char ch=getchar();
while (ch < ''||ch > ''){
if (ch == '-') x=-;
ch = getchar();
}
while (ch <= ''&&ch >= '')
{
a = a* + ch- '';
ch=getchar();
}
return x*a;
}
struct node
{
int x,y,id;
}a[maxn];
struct edge
{
int next,to,w;
}edge[maxn];
void add(int u,int v,int w)
{
edge[++tot].w=w;
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot;
}
bool cmp1(node a,node b)
{
return a.x<b.x;
}
bool cmp2(node a,node b)
{
return a.y<b.y;
}
void Dijkstra(int S)
{
q.push(make_pair(,S)); memset(vis,,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); dis[S] = ;
while(!q.empty())
{
int x = q.top().second;
q.pop();
if(vis[x])
continue;
vis[x] = ;
for(int i=head[x];i!=;i=edge[i].next)
{
int to1=edge[i].to;
if(dis[to1] > dis[x] + edge[i].w)
{
dis[to1] = dis[x] + edge[i].w ;
q.push(make_pair(-dis[to1],to1));
}
}
}
return;
}
int main()
{
n=read();
for (int i = ;i <= n;i++)
{
a[i].x=read(),a[i].y=read();
a[i].id=i;
}
sort(a+,a+n+,cmp1);
for (int i = ;i < n;i++)
{
add(a[i].id,a[i+].id,abs(a[i].x-a[i+].x));
add(a[i+].id,a[i].id,abs(a[i].x-a[i+].x));
}
sort(a+,a+n+,cmp2);
for (int i = ;i < n;i++)
{
add(a[i].id,a[i+].id,abs(a[i].y-a[i+].y));
add(a[i+].id,a[i].id,abs(a[i].y-a[i+].y));
}
Dijkstra();
cout<<dis[n];
return ;
}

Dijkstra--The Captain的更多相关文章

  1. BZOJ4152The Captain[DIjkstra]

    4152: [AMPPZ2014]The Captain Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 700  Solved: 266[Submit ...

  2. 循环队列+堆优化dijkstra最短路 BZOJ 4152: [AMPPZ2014]The Captain

    循环队列基础知识 1.循环队列需要几个参数来确定 循环队列需要2个参数,front和rear 2.循环队列各个参数的含义 (1)队列初始化时,front和rear值都为零: (2)当队列不为空时,fr ...

  3. bzoj4152 The Captain (dijkstra)

    做dijkstra,但只需要贪心地把每个点连到它左边.右边.上边.下面的第一个点就可以了 #include<bits/stdc++.h> #define pa pair<int,in ...

  4. 【bzoj4152】[AMPPZ2014]The Captain 堆优化Dijkstra

    题目描述 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. 输入 第一行包含一个正整数n(2<=n< ...

  5. BZOJ4152 The Captain(dijkstra+巧妙建图)

    BZOJ4152 The Captain 题面很简洁: 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. 很明显 ...

  6. BZOJ 4152: [AMPPZ2014]The Captain Dijkstra+贪心

    Code: #include <queue> #include <cstdio> #include <cstring> #include <algorithm ...

  7. 【堆优化Dijkstra】BZOJ4152- [AMPPZ2014]The Captain

    [题目大意] 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. [思路] 按照某维坐标排序,相邻两个点在这一维度 ...

  8. BZOJ 4152: [AMPPZ2014]The Captain( 最短路 )

    先按x排序, 然后只有相邻节点的边才有用, 我们连起来, 再按y排序做相同操作...然后就dijkstra ---------------------------------------------- ...

  9. bzoj4152[AMPPZ2014]The Captain 最短路

    4152: [AMPPZ2014]The Captain Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1517  Solved: 603[Submi ...

  10. 『The Captain 最短路建图优化』

    The Captain(BZOJ 4152) Description 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小 ...

随机推荐

  1. Tomcat+JSP经典配置实例

    经常看到jsp的初学者问tomcat下如何配置jsp.servlet和bean的问题,于是总结了一下如何tomcat下配置jsp.servlet和ben,希望对那些初学者有所帮助. 一.开发环境配置 ...

  2. 七:日期类Date、日期格式化SimpleDateFormat、日历Calendar

    日期的格式转换:

  3. is application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem

    最近试着了解 c++,接触到了QT,写了一个测试程序,在开发环境下正常后移到非开发环境,报错 网上找资料说是少了platforms文件夹中的dll,把里面所有的dll复制到执行程序目录,还是提示,继续 ...

  4. Google宣布安全奖励项目(GPSRP)覆盖上亿的 Android 应用程序

    自 2010 年推出除虫赏金项目以来,谷歌已经向安全研究人员支付了超过 1500 万美元的奖励.今天,这家科技巨头宣布进一步拓展 Google Play 安全奖励项目(GPSRP)的范围,以覆盖上亿的 ...

  5. 第1节 IMPALA:7、impala的安装以及配置过程

    6.制作本地yum源 镜像源是centos当中下载相关软件的地址,我们可以通过制作我们自己的镜像源指定我们去哪里下载impala的rpm包,这里我们使用httpd这个软件来作为服务端,启动httpd的 ...

  6. ETC系列产品非接触式读卡器方案:SI522

    随着科技的不断发展,出行上高速这是非常寻常的事.但是在很多节假日高峰时期,在高速路口塞车缴费给很多车主造成很大的烦心.为了解决这一系列的问题,科技发明了ETC这种便捷式缴费技术,让车主们顺畅通过高速路 ...

  7. SQL state [72000]; error code [1461]; ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值 ; nested exception is java.sql.BatchUpdateException: ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值

    本文转自  https://www.cnblogs.com/yingsong/p/5685790.html 原 因:某一个字段本为varchar2(1024),但是实际要插入的值超过varchar2允 ...

  8. phpstrom+win10拼音输入法不跟随情况

    PHPSTORM拼中文时悬浮框一直在右下角,真是逼死强迫症的操作! 最好解决方案: 下载讯飞输入法,虽然有点不习惯,用着用着就行了 等待官方修复着bug吧; 网上说的直接下载jre64覆盖原来的版本也 ...

  9. nodejs 编译时对项目进行配置

    1.启动项目设置配置信息 2.读取项目配置文件 3.根据配置的文件读取自定义属性 4.根据相关属性配置其他差异 5.其他

  10. 002-var_dump用法

    <?php $a = 2150; //小刘的工资2150 $b = 2240; //小李的工资2240 echo "a=" . $a . "  b=" . ...