# CF402E_Strictly Positive Matrix

题意:

有一个正方形矩阵 \(D\),大小为 n*n,其中的每个数字非负

问,是否存在一个数 k,使得 \(D^{k}\) 为一个严格正矩阵

一个严格正矩阵定义为,其中每个数都严格大于0


解:

众所周知,对于一个01邻接矩阵 \(D\),若 \(D^{k}(i,j)=1\),说明 i, j 之间存在一条经过 k 条边的路径

那么考虑本题,我们要让一个矩阵为严格正矩阵,而其中每个数本来就非负

所以,问题就是要让一些为0的数变得不为0

所以,考虑一个位置为0,若 k 无论取多少,都不能使其为正

那就意味着,无论从 i 走多少条边,都无法到达 j

那就意味着,i, j 不连通!

所以,我们看看这一张图是不是一个强连通图就好了,

跑一遍tarjan,看scc个数是不是1,完事


代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 2010;
bool a[N][N];
int dfn[N], low[N];
int stck[N], ins[N], c[N];
vector<int> scc[N];
int n, tot, num, top, cnt;

void tarjan(int x) {
    dfn[x] = low[x] = ++num;
    stck[++top] = x, ins[x] = 1;
    for (int y = 1; y <= n; y++) {
        if (a[x][y] == 0) continue;
        if (!dfn[y]) {
            tarjan(y);
            low[x] = min(low[x], low[y]);
        } else if (ins[y])
            low[x] = min(low[x], dfn[y]);
    }

    if (dfn[x] == low[x]) {
        cnt++; int y;
        do {
            y = stck[top--], ins[y] = 0;
            c[y] = cnt, scc[cnt].push_back(y);
        } while (x != y);
    }
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++) {
            int tmp;
            scanf("%d", &tmp);
            if (tmp != 0) a[i][j] = true;
            else a[i][j] = false;
        }
    for (int i = 1; i <= n; i++)
        if (!dfn[i]) tarjan(i);
    if (cnt == 1) cout << "YES" << endl;
    else cout << "NO" << endl;
}
posted @ 2020-08-27 16:35  熹圜  阅读(162)  评论(0)    收藏  举报