Floyd算法(插点法):阈值距离内邻居最少的城市

Floyd算法(插点法):阈值距离内邻居最少的城市

问题:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路:

此题可将每个节点到其他节点的最短路求出,最后对距离矩阵遍历得到结果,即转化为多源最短路问题,可采用Floyd算法

Floyd算法的思想是DP:
通过已知条件初始化距离矩阵D[n][n],其中D[i][j]表示,顶点i到顶点j的距离。

n个顶点依次作为插入点,例如,k为其中一个顶点,
若D[i][k] + D[k][j] < D[i][j],那说明顶点i经过顶点k再到达j,比直接到达j要近。所以更新D[i][j]:D[i][j] = D[i][k] + D[k][j]。

可以归纳得到状态转移方程:
D[i][j] = min(D[i,k]+D[k,j],D[i,j]);

为什么插入点k放在第一层循环中:
二维状态转移方程D[i][j] = min(D[i,k]+D[k,j],D[i,j]) 其实是从三维简化得到的:

首先定义状态数组(也就是距离矩阵)D[n][n][n],其中D[k][i][j]表示顶点i, 顶点j通过前k个顶点(0~k)得到的最短距离。

D[k][i][j]是从D[k-1][i][j]和D[k-1][i][k] + D[k-1][k][j]两者中值较小的一个转移得到的,也就是说要在前k-1个顶点已经插入,更新距离矩阵状态之后,第k个顶点才能作为插入顶点。

归纳得到状态转移方程:
D[k][i][j] = min(D[k-1][i][j], D[k-1][i][k] + D[k-1][k][j])。

其中k的作用是标志到达了第几个插入点,也就是状态数组到达了哪个状态,减去第一维就将k的变化变成了第一层循环,而距离矩阵变成了二维

代码:

class Solution {
public:
    int findTheCity(int n, vector<vector<int>>& edges, int distanceThreshold) {
        vector<vector<int>> D( n,vector<int>( n,1e+06 ) );
        for( auto temp:edges )
        {
            D[ temp[0] ][ temp[1] ]=temp[2];
            D[ temp[1] ][ temp[0] ]=temp[2];
        }
        int k,i,j;
        for( k=0;k<n;k++ )
        {
            for( i=0;i<n;i++ )
                for( j=0;j<n;j++ )
                {
                    if( i==j  || D[i][k]>1e+05 || D[k][j]>1e+05 )
                        continue;
                    D[i][j]=min( D[i][k]+D[k][j],D[i][j] );
                }
        }
        int max=101;
        int flag;
        for( i=0;i<n;i++ )
        {   
            int ans=0;
            for( j=0;j<n;j++ )
            {
                if( i!=j && D[i][j]<=distanceThreshold )
                    ans++;
            }
            if( ans<=max )
            {
                max=ans;
                flag=i;
            }
        }
        return flag;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

happy19991001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值