# 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;
}

浙公网安备 33010602011771号