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;
}
};
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/153834.html