[bzoj4152][AMPPZ2014]The Captain dijkstra

本文介绍了一道经典的最短路径问题——AMPPZ2014 TheCaptain,通过给定平面上的n个点,求从1号点到n号点的最小费用路径。采用贪心策略建立边关系,并使用Dijkstra算法求解最短路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

4152: [AMPPZ2014]The Captain

Time Limit: 20 Sec   Memory Limit: 256 MB
[ Submit][ Status][ Discuss]

Description

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

Input

第一行包含一个正整数n(2<=n<=200000),表示点数。
接下来n行,每行包含两个整数x[i],y[i](0<=x[i],y[i]<=10^9),依次表示每个点的坐标。

Output

一个整数,即最小费用。

Sample Input

5
2 2
1 1
4 5
7 1
6 7

Sample Output

2

HINT

此题卡spfa

Source

贪心建边,再跑最短路
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define INF 100000000000000ll
#define pa pair<long long,int>
using namespace std;
typedef long long ll;
const int N = 200000 + 5;
int last[N],n,cnt;
ll dis[N];
struct data{
	int u,v,id;
}da[N];
struct Edge{
	int to,next; ll v;
}e[N*4];
bool vis[N];
bool cmp1( data a, data b ){ return a.u < b.u; }
bool cmp2( data a, data b ){ return a.v < b.v; }
void insert( int u, int v, ll w ){
	e[++cnt].to = v; e[cnt].next= last[u]; e[cnt].v = w; last[u] = cnt;
	e[++cnt].to = u; e[cnt].next= last[v]; e[cnt].v = w; last[v] = cnt;
}
priority_queue<pa,vector<pa>,greater<pa> > q;
void dijkstra(){
	memset(vis,0,sizeof(vis));
	for( int i = 1; i <= n; i++ ) dis[i] = INF;
	dis[1] = 0; q.push(make_pair(0,1));
	while( !q.empty() ){
		int now = q.top().second; q.pop();
		if( vis[now] ) continue; vis[now] = 1;
		for( int i = last[now]; i; i = e[i].next ){
			if( dis[now] + e[i].v < dis[e[i].to] ){
				dis[e[i].to] = dis[now] + e[i].v;
				q.push(make_pair(dis[e[i].to],e[i].to));
			}
		}
	}
}
int main(){
	scanf("%d", &n);
	for( int i = 1; i <= n; i++ ){ scanf("%d%d", &da[i].u, &da[i].v); da[i].id = i; }
	std::sort( da+1, da+n+1, cmp1 );
	for( int i = 1; i < n; i++ )
		insert( da[i].id, da[i+1].id, da[i+1].u - da[i].u );
	std::sort( da+1, da+n+1, cmp2 );
	for( int i = 1; i < n; i++ )
		insert( da[i].id, da[i+1].id, da[i+1].v - da[i].v );
	dijkstra();
	printf("%lld",dis[n]);
	return 0;
}#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define INF 100000000000000ll
#define pa pair<long long,int>
using namespace std;
typedef long long ll;
const int N = 200000 + 5;
int last[N],n,cnt;
ll dis[N];
struct data{
	int u,v,id;
}da[N];
struct Edge{
	int to,next; ll v;
}e[N*4];
bool vis[N];
bool cmp1( data a, data b ){ return a.u < b.u; }
bool cmp2( data a, data b ){ return a.v < b.v; }
void insert( int u, int v, ll w ){
	e[++cnt].to = v; e[cnt].next= last[u]; e[cnt].v = w; last[u] = cnt;
	e[++cnt].to = u; e[cnt].next= last[v]; e[cnt].v = w; last[v] = cnt;
}
priority_queue<pa,vector<pa>,greater<pa> > q;
void dijkstra(){
	memset(vis,0,sizeof(vis));
	for( int i = 1; i <= n; i++ ) dis[i] = INF;
	dis[1] = 0; q.push(make_pair(0,1));
	while( !q.empty() ){
		int now = q.top().second; q.pop();
		if( vis[now] ) continue; vis[now] = 1;
		for( int i = last[now]; i; i = e[i].next ){
			if( dis[now] + e[i].v < dis[e[i].to] ){
				dis[e[i].to] = dis[now] + e[i].v;
				q.push(make_pair(dis[e[i].to],e[i].to));
			}
		}
	}
}
int main(){
	scanf("%d", &n);
	for( int i = 1; i <= n; i++ ){ scanf("%d%d", &da[i].u, &da[i].v); da[i].id = i; }
	std::sort( da+1, da+n+1, cmp1 );
	for( int i = 1; i < n; i++ )
		insert( da[i].id, da[i+1].id, da[i+1].u - da[i].u );
	std::sort( da+1, da+n+1, cmp2 );
	for( int i = 1; i < n; i++ )
		insert( da[i].id, da[i+1].id, da[i+1].v - da[i].v );
	dijkstra();
	printf("%lld",dis[n]);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值