floyd求路径

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#include <cmath>
#include <string.h>
#define R(x) x = read()
#define For(i, j, n) for (int i = j; i <= n; ++i)
using namespace std;

inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

const int N = 1005;

int n, m;
int g[N][N], f[N][N], ans[N][N];

void floyd()
{
    for(int k = 1; k <= n; k++)
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
            {
                //f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
                if(f[i][j] > f[i][k] + f[k][j])
                {
                    f[i][j] = f[i][k] + f[k][j];
                    ans[i][j] = k;
                }
            }
}

int path[N], cnt;

void solve(int a, int b)
{
    if(!ans[a][b])
        return;
    //path[++cnt] = a;
    solve(a, ans[a][b]);
    path[++cnt] = ans[a][b];
    solve(ans[a][b], b);
    //path[++cnt] = b;
}

void print_path(int a, int b)
{
    if(f[a][b] >= 1000000)
    {
        puts("can not reach");
        return;
    }
    memset(path, 0, sizeof(path));
    cnt = 0;
    path[++cnt] = a;
    solve(a, b);
    path[++cnt] = b;
    printf("the path between %d and %d\n", a, b);
    for(int i = 1; i <= cnt; i++)
        printf("%d ", path[i]);
    puts("");
}

int main()
{
    R(n);R(m);
    memset(f, 0x3f, sizeof(f));
    For(i, 1, m)
    {
        f[i][i] = 0;
    }
    For(i, 1, m)
    {
        int a, b, c;
        R(a);R(b);R(c);
        f[a][b] = min(f[a][b], c);
    }
    floyd();
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
        {
            if(i == j)
            {
                puts("the same point");
                continue;
            }
            print_path(i, j);
        }
    return 0;
}

注意:

void solve(int a, int b)
{
    if(!ans[a][b])
        return;
    //path[++cnt] = a;
    solve(a, ans[a][b]);
    path[++cnt] = ans[a][b];
    solve(ans[a][b], b);
    //path[++cnt] = b;
}

这里不能把起点和终点也算上,因为这一轮的中间点,下一轮就变成起点/终点了,如果算上会导致重复。

posted @ 2024-04-03 22:03  Gold_stein  阅读(2)  评论(0编辑  收藏  举报