4152. [AMPPZ2014]The Captain
显然稠密图的边数时 n 2 n^2 n2量级,我们不可能把所有边建立出来,这时候通常寻求一些性质详细见【论题选编】稠密图最短路
针对本题我们可以先这样考虑,假设每个点有且只有一维信息,那么任意两点之间的距离可以写为 ∣ x i − x j ∣ |x_i-x_j| ∣xi−xj∣
首先我们对 x x x进行排序,并且考虑相邻的三个点 i , j , k i,j,k i,j,k,显然我们只需要在 i , j i,j i,j以及 j , k j,k j,k之间连边对于 i → k i\to k i→k这条边没有必要去连。
稍微思考一下二维同样也是如此,详细也可以看上述博客博主解释
#include<queue>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
using pii=pair<int,int>;
using ll=long long;
constexpr int N=200010,M=800010;
int h[N],e[M],ne[M],w[M],idx;
void add(int a,int b,int c){e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;}
int n;
struct node
{
int x,y,id;
}q[N];
ll d[N];
bool st[N];
void dijkstra()
{
priority_queue<pii,vector<pii>,greater<pii>> q;
memset(d,0x3f,sizeof d);
memset(st,0,sizeof st);
d[1]=0;
q.push({0,1});
while(q.size())
{
int u=q.top().second;q.pop();
if(st[u]) continue;
st[u]=1;
for(int i=h[u];i!=-1;i=ne[i])
{
int v=e[i];
if(d[v]>d[u]+w[i])
{
d[v]=d[u]+w[i];
q.push({d[v],v});
}
}
}
}
int main()
{
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
cin>>n;
memset(h,-1,sizeof h);
for(int i=1;i<=n;i++)
{
int x,y;
cin>>x>>y;
q[i]={x,y,i};
}
sort(q+1,q+1+n,[](const node &a,const node&b){return a.x<b.x;});
for(int i=1;i<n;i++)
{
int u=q[i].id,v=q[i+1].id,c=q[i+1].x-q[i].x;
add(u,v,c),add(v,u,c);
}
sort(q+1,q+1+n,[](const node &a,const node&b){return a.y<b.y;});
for(int i=1;i<n;i++)
{
int u=q[i].id,v=q[i+1].id,c=q[i+1].y-q[i].y;
add(u,v,c),add(v,u,c);
}
dijkstra();
cout<<d[n]<<'\n';
return 0;
}