*传送

给定平面上的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. No 'Access-Control-Allow-Origin'跨域问题- (mysql-thinkphp) (6)

    因为ajax请求一个服务的时候,服务器端,比如thinkphp端,或者java框架,它会检测,你请求时候的域名,就是http请求的时候,request header不是会把客户端的Request UR ...

  2. 查看oracle单签session

    转自 https://blog.csdn.net/alexsong123/article/details/51858092 怎样查看oracle当前的连接数呢?只需要用下面的SQL语句查询一下就可以了 ...

  3. 前端构建工具gulp超详细配置, 使用教程(图文)

    流程 1. 输入命令(可以使用git bash或者命令控制台cmd) npm install -g gulp 安装全局gulp命令 2. 创建一个项目文件夹, 当前项目文件夹下输入命令npm init ...

  4. [Codeforces #608 div2]1271A Suits

    Description A new delivery of clothing has arrived today to the clothing store. This delivery consis ...

  5. django中使用ORM模型修改数据库的表名

    在django中,使用models.py创建好一张表后,如果不指定表的名字,那么表的名字就默认为 model_modelname 例如: class Book(models.Model): id = ...

  6. awk&sed

    sed BRE       awk  ERE sed 不能采用?   awk可以 sed 在匹配的任何时候可以用^,$ awk必须除了在行头和行尾 其他地方必须转义

  7. POJO,JavaBean,entity的理解

    POJO本质是就是JavaBean JavaBean JavaBean实际上是指一种特殊的Java类,它通常用来实现一些比较常用的简单功能,并可以很容易的被重用或者是插入其他应用程序中去.所有遵循“一 ...

  8. centos7安装google-chrome和chromedriver

    1.root用户下进入到etc/yum.repos.d目录下  [root@f7d6b9f2-1291-4d2f-8805-aef94deac9f7 yum.repos.d]# pwd  /etc/y ...

  9. UVA - 10129 Play on Words(欧拉回路)

    题意:将n个单词排成一个序列,保证相邻单词相邻处字母相同. 分析:每个单词看做一条有向边,字母为点,并查集看图是否连通,因为是有向图,所以最多只能有两个点入度不等于出度,且这两个点一个入度比出度大1, ...

  10. POJ 3983:快算24

    快算24 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4791   Accepted: 2930 Description ...