*传送

给定平面上的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. 隐患写法flag.equals("true")带来的空指针异常

    分类:2008-06-04 12:47 467人阅读 评论(0) 收藏 举报 linuxjava测试 昨天,有同事A对同事B写的程序进行测试时,出现错误,看控制台信息,发现抛出了空指针异常. 调查结果 ...

  2. python-python基础3

    本章内容: 函数 递归 高阶函数 一.函数 一个函数一般完成一项特定的功能 函数使用     函数需要先定义     使用函数,调用

  3. NO31 配置网卡--主机名--网络故障排查面试题--DNS

    修改网卡配置信息: 修改主机名规范的三个步骤: 配置默认网关: DNS解析过程,用命令看:  DNS相关命令: 口述DNS解析过程: 客户端(电脑)通过浏览器输入域名,先找hosts文件及本地dns缓 ...

  4. STM32学习笔记:IIC通信协议详解(附带软件模拟源码)

    什么是IIC(I2C)? IIC 即Inter-Integrated Circuit(集成电路总线),这种总线类型是由飞利浦半导体公司设计出来的一种简单.双向.二线制.同步串行总线.它是一种多向控制总 ...

  5. 外网如何访问 Service?【转】

    除了 Cluster 内部可以访问 Service,很多情况我们也希望应用的 Service 能够暴露给 Cluster 外部.Kubernetes 提供了多种类型的 Service,默认是 Clus ...

  6. Elasticsearch学习入门

    一.关于Elasticsearch 1.特点 Elasticsearch基于全文搜索引擎 Apache Lucene ,由Java开发而来,面向API进行搜索, Restful 风格,分布式文件存储. ...

  7. MySQL 中的数据库名称、数据表名称、字段名称

    如何查询Oracle,Sql Server,MySQL 中的数据库名称.数据表名称.字段名称 分类: Database2012-09-24 22:16 7034人阅读 评论(0) 收藏 举报 数据库s ...

  8. 我的第一个爬虫【python selenium】

    去年写的一个小功能,一年过得好快,好快! 目的:爬取京东商品详情页面的内容(商品名称.价格.评价数量)后存储到xls文档中,方便商家分析自己商品的动态. 软件:chrome(windows).chro ...

  9. eclipse环境变量设置

    eclipse的运行需要java,但是当安装了多个版本的jdk后,eclipse可能就不能用了. 解决办法就是: #eclipse 文件夹下有eclipse.ini配置文件,在文件首行添加如下信息: ...

  10. 038、Java中逻辑运算之非运算“!”

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...