题目大意
给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用。
题目的意思就是三角形中会走较短的直角边
首先考虑暴力建边,每两个点中间建一条边
然后跑一遍最短路,但是效率不够
那么怎么优化呢
如图所示,假设b<a c<d a+c<b+d;
首先看A到D的距离,会走a+c;
然后A到B会走b,B到D会走c,
那么通过B中转的花费为:b+c;不通过B中转的花费为:a+c;
又因为a>b,所以通过B中转的花费会少,
最糟糕的情况不过就是花费相等,所以两相邻点间连线后任意两点间路径就会尽可能短,从而缩减所建边数;
所以这题主要是建边
以上为主要思路,下面的为建边细节,理解的同学可以撤了(下边的是废话没用了)
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>dian[i].x>>dian[i].y;
dian[i].id=i;
}
sort(dian+1,dian+1+n,cmx);
for(int i=1;i<n;i++)
{
int u=dian[i].id;int v=dian[i+1].id;
addedge(u,v,dian[i+1].x-dian[i].x);
addedge(v,u,dian[i+1].x-dian[i].x);
}
sort(dian+1,dian+1+n,cmy);
for(int i=1;i<n;i++)
{
int u=dian[i].id;int v=dian[i+1].id;
addedge(u,v,dian[i+1].y-dian[i].y);
addedge(v,u,dian[i+1].y-dian[i].y);
}
首先分别以横纵坐标顺序对点排序,这样横纵相邻的点就在一起了
然后在横坐标排序后两点间建一条长度为两点间横坐标差值的边,纵坐标排序后两点间建一条长度为纵坐标差值的边;
这难道不会出问题吗?假设两点间按题意走的是横边(横着的那条直角边)而这两点偏偏链的是纵边怎么办呢?
或者说会有其他什么问题?
其实是不会的
假设两点间竖直直连的费用为a,竖直通过其他点中转的费用为b,横向直连的费用为c
那么b<=a
算法会在b和c中取最小的
假设取到c,那么c<b那么c一定会小于a
假设取到b,那么就不会直接走过去所以限制也就不存在了
若两点横纵坐标都相邻,算法依旧会取最小,所以完全没问题。
写在后面
我几乎翻遍了网上所有关于这题的题解,写的都很简略,而且都说这是简单题
包括我身边的同学都觉得没毛病,很简单,果然是我太蒻了吗233333333
但是我觉得需要深入思考一下(╯‵□′)╯︵┻━┻