1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//! ワーシャルフロイト
pub fn floyd_warshall(matrix: &[Vec<Option<i64>>]) -> Vec<Vec<Option<i64>>> {
    let mut m: Vec<_> = matrix.to_vec();
    let n = m.len();
    (0..n).for_each(|i| {
        (0..n).for_each(|j| {
            (0..n).for_each(|k| {
                m[j][k] = if m[j][k].is_none() && m[j][i].is_none() && m[i][k].is_none() {
                    None
                } else if m[j][i].is_none() || m[i][k].is_none() {
                    m[j][k]
                } else if m[j][k].is_none() {
                    Some(m[j][i].unwrap() + m[i][k].unwrap())
                } else {
                    Some(std::cmp::min(
                        m[j][k].unwrap(),
                        m[j][i].unwrap() + m[i][k].unwrap(),
                    ))
                };
            })
        })
    });
    m
}
#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_floyd_warshall_1() {
        let matrix = vec![
            vec![Some(0), Some(1), Some(1), None, Some(1)],
            vec![Some(1), Some(0), Some(1), Some(1), None],
            vec![Some(1), Some(1), Some(0), Some(1), Some(1)],
            vec![None, Some(1), Some(1), Some(0), Some(1)],
            vec![Some(1), None, Some(1), Some(1), Some(0)],
        ];
        let a = floyd_warshall(&matrix);

        let ans = vec![
            vec![Some(0), Some(1), Some(1), Some(2), Some(1)],
            vec![Some(1), Some(0), Some(1), Some(1), Some(2)],
            vec![Some(1), Some(1), Some(0), Some(1), Some(1)],
            vec![Some(2), Some(1), Some(1), Some(0), Some(1)],
            vec![Some(1), Some(2), Some(1), Some(1), Some(0)],
        ];

        assert_eq!(ans, a);
    }

    #[test]
    fn test_floyd_warshall_2() {
        let matrix = vec![
            vec![Some(0), Some(10), None, Some(100)],
            vec![None, Some(0), None, Some(1000)],
            vec![None, Some(1), Some(0), Some(10000)],
            vec![Some(5), None, None, Some(0)],
        ];

        let a = floyd_warshall(&matrix);
        let ans = vec![
            vec![Some(0), Some(10), None, Some(100)],
            vec![Some(1005), Some(0), None, Some(1000)],
            vec![Some(1006), Some(1), Some(0), Some(1001)],
            vec![Some(5), Some(15), None, Some(0)],
        ];
        assert_eq!(ans, a);
    }
}