洛谷题解 P1744 【采购特价商品】

分析:

这个题通过简单的分析题意,可以看出,显然是一道

SPFA的题(标签里的。。。。。。)

## But 本人太弱。。。。。。

NO Problem,无伤大雅

我们用Floyd来代替一下

这道题求任意两点之间的距离,众所周知,Floyd可以求任意两点的最短路,而且包括负边权,很强大


先补充一点预备知识:

两点间距离公式:对于平面上两点(x1,y1),(x2,y2)他们的直线距离为

\[ \sqrt {(x1-x2)^2+(y1-y2)^2} \]


代码

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
int a[101][3];
double f[101][101]  //f[i][j]表示i点到j点的最短路;
int n,i,j,k,x,y,m,s,e;
int main(){
    cin>>n;
    for(i=1;i<=n;i++) cin>>a[i][1]>>a[i][2];
    cin>>m; 
    memset(f,0x7f,sizeof(f));  //在没有已知连接不连接的情况下,对于有权值的图
                                //我们全部预处理成无限大 
    for(i=1;i<=m;i++){         //对于有连接的,我们用两点间距离公式更新距离 
        cin>>x>>y;  //第二次输入有连接的 
        f[y][x]=f[x][y]=sqrt(pow(double(a[x][1]-a[y][1]),2)+pow(double(a[x][2]-a[y][2]),2));
    }
    cin>>s>>e;  //原点和目标点 
    //Floyd关键部分 
    for(k=1;k<=n;k++){
        for(i=1;i<=n;i++){
            for(j=1;j<=n;j++){
                if((i!=j)&&(i!=k)&&(j!=k)&&(f[i][k]+f[k][j]<f[i][j])) f[i][j]=f[i][k]+f[k][j];
                //如果有一个点k,使原先找到的最短路f[i][j]更短,则更新 
            }
        }
    }
    printf("%.2lf\n",f[s][e]);    //输出要求的 
    return 0;
}

但是我发现有一个更好的做法

优化核心思想

当原点和目标点之间有连线的时候,我们用两点之间距离公式求出来的距离就是最短路。我们可以加一个特判,即f[i][j]不是无穷大时,输出,结束。这样就可以少跑一边Floyd,对于某些数据,可以稍快一点。

代码请读者自行思考

猜你喜欢

转载自www.cnblogs.com/RiaOIer-Blog/p/12287762.html