---
# System prepended metadata

title: Floyd–Warshall algorithm

---

# Floyd–Warshall algorithm

## 7
The recursive formula is
![](https://i.imgur.com/EhhRVwj.png)




We can use $\Phi$ to reconstruct the shortest paths.

The new version of Floyd–Warshall algorithm is

```python=
// D is a array of n n×n matries;
// Φ is a array of n n×n matries;
n = W.rows;
D[0] = W ;
Φ[0] = NIL;
for k = 1 to n do:
    let D[k] be a new n×n matrix;
    let Φ[k] be a new n×n matrix;
    for i = 1 to n do:
        for j = 1 to n do
            if D[k-1][i][k] + D[k-1][k][j] < D[k-1][i][j]: 
                D[k][i][j] = D[k-1][i][k] + D[k-1][k][j]
                Φ[k][i][j] = k
            else:
                D[k][i][j] = D[k-1][i][j]
                Φ[k][i][j] = Φ[k-1][i][j]

```
PRINT-ALL-PAIRS-SHORTEST-PATH(Φ, i, j)
```python=
if i == j then:
    print i;
elif Φ[i][j] == NIL:
    print ”no path from ” i ” to ” j ” exists”.;
else:
    PRINT-ALL-PAIRS-SHORTEST-PATH(Φ, i, Φ[i][j] );
```


## why the triple for-loop starts with k?

```python=
for k in range(1, n+1):
    for i in range(1, n+1):
        for j in range(1, n+1):
            dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j])
    
```

### 好懂的解釋
2022-07-10T17-45
本質是：
```
for k in 1~N:
    用k試圖插入所有邊  插入居中看看  看會不會更短
    當嘗試完k=kk時  對於任兩點都已經是在可以自由取用1~kk以任意順序建構中途路徑下的最短
```

定義Func(1~kk):
對於任兩點都已經是在可以自由取用1~kk以任意順序建構中途路徑下的最短

Func(1~kk) 可以輕易的從 Func(1~(kk-1)) 推出來 的dp本質

![](https://hackmd.io/_uploads/HkoReTuiq.jpg)


### 知乎
https://www.zhihu.com/question/30955032?sort=created

1
![](https://hackmd.io/_uploads/SkP283di5.png)
2
![](https://hackmd.io/_uploads/SkTjD2uj5.png)
 

## c++


LC-CN
https://leetcode.cn/problems/find-the-city-with-the-smallest-number-of-neighbors-at-a-threshold-distance/solution/zui-duan-lu-jing-mo-ban-da-ji-he-cban-fl-gs7u/


### fatest

    const int INF = 0x3f3f3f3f;
    int dist[n][n];
    memset(dist,INF,sizeof(dist));
    
why 0x3f3f3f3f
https://hackmd.io/Vw-WHs4cRuSv7f8CBWwOSw

```cpp=
class Solution {
public:
    int findTheCity(int n, vector<vector<int>>& edges, int distanceThreshold) {
        const int INF = 0x3f3f3f3f;
        int dist[n][n];
        memset(dist,INF,sizeof(dist));
        for(int i=0;i<n;i++)
        dist[i][i]=0;
        for(int i=0;i<edges.size();i++){
            dist[edges[i][0]][edges[i][1]]=edges[i][2];
            dist[edges[i][1]][edges[i][0]]=edges[i][2];
        }
        for(int k=0;k<n;k++){
            for(int i=0;i<n;i++){
                for(int j=0;j<n;j++){
                    dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
                }
            }
        }
        int id=-1, minCnt=INF;
        for(int i=0;i<n;i++){
            int cnt=0;
            for(int j=0;j<n;j++){
                if(dist[i][j]<=distanceThreshold)
                    cnt++;
            }
            if(cnt<=minCnt){
                minCnt=cnt;
                id=i;
            }
        }
        return id;
    }
};
```

### vector

    vector<vector<int>>distances(n,vector<int>(n,INT_MAX)); //全源最短路径矩阵
                                                 ^^^^^^^
                                         2D vector 初始值
        
        
```cpp=
class Solution {
public:
    void Floyd(vector<vector<int>>& distances, int n){
        for (int k=0; k<n; ++k) {
            for (int i=0; i<n; ++i) {
                for (int j=0; j<n; ++j) {
                    if (distances[i][k]!=INT_MAX && distances[k][j] != INT_MAX && distances[i][k] + distances[k][j] < distances[i][j]) {
                        distances[i][j] = distances[i][k] + distances[k][j];
                    }
                }
            }
        }
    }
    int findTheCity(int n, vector<vector<int>>& edges, int distanceThreshold) {
        vector<vector<int>>distances(n,vector<int>(n,INT_MAX)); //全源最短路径矩阵
        for (int i=0; i<n; i++) {
            distances[i][i] = 0; //自身到自身的距离为0
        }
        for (vector<int> edge : edges) {
            int u=edge[0], v=edge[1], w=edge[2];
            distances[u][v]=w;
            distances[v][u]=w;
        }
        Floyd(distances, n);
        int idx = -1, minCount = INT_MAX;
        for (int i=0; i<n; ++i) {
            int count = 0;
            for (int j=0; j<n; ++j) {
                if (distances[i][j]<=distanceThreshold && i!=j) {
                    count++;
                }
            }
            if (count <= minCount) {
                minCount = count;
                idx = i;
            }
        }
        return idx;
    }
};


作者：sui-xin-yuan
链接：https://leetcode.cn/problems/find-the-city-with-the-smallest-number-of-neighbors-at-a-threshold-distance/solution/zui-duan-lu-jing-mo-ban-da-ji-he-cban-fl-gs7u/
来源：力扣（LeetCode）
著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。
```