AcWing 854. Floyd求最短路

AcWing 854. Floyd求最短路_第1张图片

很明显一看,这是多源最短路径问题,看完y总视频才知道,多源最短路径比单源最短路径简单不少。
根据y总所说,多源最短路径的基本思路是dp,怎么dp的呢,首先,
我们先设一个数组d[k,i,j],这代表什么呢,首先k是指经过前k个点,从i-j的最短距离,然后我们开始dp
d[k,i,j]=min(d[k-1,i,j],d[i][k]+d[k][j])
这是最核心的式子,经过第k个点的距离,与之前的遍历结果进行比较不断更新距离值,最后输出d[n][i][j]即可。
然后我们其实可以写成二维的式子,这样大大减少了空间复杂度。
于是代码如下。

#include
#include
#include

using namespace std;

const int N=210,Inf=1e9;

int g[N][N];
int n,m,k;

int main(void)
{
     
    scanf("%d%d%d",&n,&m,&k);
    for(int j=1;j<=n;j++)//在初始化g[i][j]的操作的时候我刚开始用memeset,发现好像不是很好用,然后要
    //是赋值0x3f3f3f3f太大了,会溢出。
    for(int i=1;i<=n;i++)
    if(i==j)
    g[i][j]=0;//需要注意自己到自己为0
    else
    g[i][j]=Inf;
    for(int i=1;i<=m;i++)
    {
     
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        g[a][b]=min(g[a][b],c);//会出现重边的情况,所以要取最小值,我们用的是邻接矩阵,所以我们要更新操作
        //好像邻接表不用取更新,在后续的操作会自动把大的值忽略掉。
    }
    for(int p=1;p<=n;p++)
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    {
     
        g[i][j]=min(g[i][j],g[i][p]+g[p][j]);
    }
    for(int i=1;i<=k;i++)
    {
     
        int a,b;
        scanf("%d%d",&a,&b);
        if(g[a][b]>Inf/2)
        printf("impossible\n");
        else
        printf("%d\n",g[a][b]);
        
    }
}

你可能感兴趣的:(acwing,c++,数据结构,编程语言,算法)