ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[JLOI2011]飞行路线题解

2022-08-13 17:02:14  阅读:211  来源: 互联网

标签:node JLOI2011 min int 题解 200010 路线 edge id


The Captain

@

目录

题目描述

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

分析

我们第一时间会想把所有点都连上边,这样在跑一遍dijkstra,不就可以了吗?
但是

对于100%的数据,n<=200000

那我们就想一下如何优化呢
我从样例哪里拿来3个数来看一下

id x y
1 2 2
2 1 1
3 4 5

1到2,需要$min(|X_1-X_2|,|Y_1-Y_2|)=1费用$
1到3,需要$min(|X_1-X_3|,|Y_1-Y_3|)=2费用$
2到3,需要$min(|X_2-X_3|,|Y_2-Y_3|)=3费用$
$1+2=3$难道是巧合?
我们来分析一下

  • 如果$|X_1-X_2|$和$|X_1-X_3|$都是最小或最大的话,那么把$X_1$当成中转站$|X_1-X_2|+|X_1-X_3|=|X_2-X_3|$、
  • 如果$|X_1-X_2|$和$|X_1-X_3|$是一个大,一个小的话,那么把$X_1$当成中转站$|X_1-X_2|+|X_1-X_3|<|X_2-X_3|$

所以我们可以把$X$排序,相邻存边;在把$Y$排序,相邻存边,一共存$4n$条边
这部分的代码我就不放了,到后面去看吧

代码

有点长

#include<bits/stdc++.h>
using namespace std;
int n,d[200010];
struct node
{
	int x,y,id;
}a[200010];
struct edge
{
	int x,s;
	bool operator<(const edge&a)const
    {
        return s>a.s;
    }
};
bool cmpx(node a,node b)
{
	if(a.x==b.x)return a.y<b.y;
	return a.x<b.x;
}
bool cmpy(node a,node b)
{
	if(a.y==b.y)return a.x<b.x;
	return a.y<b.y;
}
int f(node a,node b)
{
	return min(abs(a.x-b.x),abs(a.y-b.y));
}
vector<edge> v[200010];
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i].x>>a[i].y;
		a[i].id=i;
	}
	sort(a+1,a+n+1,cmpx);
	for(int i=1;i<n;i++)
	{
		v[a[i].id].push_back(edge{a[i+1].id,f(a[i],a[i+1])});
		v[a[i+1].id].push_back(edge{a[i].id,f(a[i],a[i+1])});
	}
	sort(a+1,a+n+1,cmpy);
	for(int i=1;i<n;i++)
	{
		v[a[i].id].push_back(edge{a[i+1].id,f(a[i],a[i+1])});
		v[a[i+1].id].push_back(edge{a[i].id,f(a[i],a[i+1])});
	}
	priority_queue<edge> q;
	q.push(edge{1,0});
	for(int i=2;i<=n;i++)d[i]=1e9;
	while(!q.empty())
	{
		edge x=q.top();
		q.pop();
		if(x.s!=d[x.x])continue;
		for(int i=0;i<v[x.x].size();i++)
		{
			edge y=v[x.x][i];
			if(d[y.x]>d[x.x]+y.s)
			{
				d[y.x]=d[x.x]+y.s;
				q.push(edge{y.x,d[x.x]+y.s});
			}
		}
	}
	cout<<d[n];
}

祝大家AC大吉

标签:node,JLOI2011,min,int,题解,200010,路线,edge,id
来源: https://www.cnblogs.com/gdfzlcx/p/16583467.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有