洛谷题单指南-最短路-B3611 【模板】传递闭包

原题链接:https://www.luogu.com.cn/problem/B3611

题意解读:求传递闭包,floyd算法的应用。

解题思路:

此题需要利用动态规划思想

1、状态表示

设g[i][j][k]=1表示从i经过1~k的点可以到j,g[i][j][k]=0则表示i不能到j

2、状态转移

考虑从i到j是否经过k点,有两种可能:

  • 经过k点,则有g[i][j][k] = g[i][k][k-1] & g[k][j][k-1]
  • 不经过k点,则有g[i][j][k] = g[i][j][k-1]

综合得到:g[i][j][k] = g[i][j][k-1] | g[i][k][k-1] & g[k][j][k-1]

由于第三维只依赖上一层,可以滚动数组优化,进而可以直接省掉这一维

则有:g[i][j] = g[i][j] | g[i][k] & g[k][j]

3、初始化

如果i到j有一条路径,则g[i][j] = 1

4、答案

输出所有的g[i][j]

100分代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 105;
int g[N][N];
int n;

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            cin >> g[i][j];
            
    for(int k = 1; k <= n; k++)
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                g[i][j] = g[i][j] | g[i][k] & g[k][j];

    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= n; j++)
            cout << g[i][j] << " ";
        cout << endl;
    }
        
    return 0;
}

 

posted @ 2025-04-04 00:15  hackerchef  阅读(59)  评论(0)    收藏  举报