4152. [AMPPZ2014]The Captain
显然稠密图的边数时n2n^2n2量级,我们不可能把所有边建立出来,这时候通常寻求一些性质详细见【论题选编】稠密图最短路
针对本题我们可以先这样考虑,假设每个点有且只有一维信息,那么任意两点之间的距离可以写为∣xi−xj∣|x_i-x_j|∣xi−xj∣
首先我们对xxx进行排序,并且考虑相邻的三个点i,j,ki,j,ki,j,k,显然我们只需要在i,ji,ji,j以及j,kj,kj,k之间连边对于i→ki\to ki→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;
}