「Codeforces 402E」Strictly Positive Matrix

Description

题目链接:Codeforces 402E

你有一个 $n\times n$ 的矩阵 $a$。它满足如下性质:

  • 对于任意的 $i,j$($1\le i,j\le n$)都有 $a_{i,j}\ge 0$。
  • $\sum_{i=1}^n a_{i,i}=0$

矩阵 $b$ 是严格正矩阵当且仅当对于任意的 $i,j$($1\le i,j\le n$)都有 $b_{i,j}>0$。

求是否存在整数 $k\ge 1$ 使得 $a^k$ 是一个严格正矩阵。

数据范围:$2\le n\le 2\times 10^3$,$0\le a_{i,j}\le 50$,$\sum_{i=1}^n a_{i,i}=0$


Solution

首先我们把这个矩阵转化为 $01$ 矩阵,它的 $k$ 次方代表着对它进行 $k$ 次迭代,得到的矩阵记为 $a’$。那么$a’_{i,j}=1$ 当且仅当邻接矩阵 $a$ 形成的图中 $i$ 到 $j$ 有一条长度为 $k$ 的路径(并非是简单路径),也就是走 $k$ 次后图的连通性。

这样一来,我们把矩阵问题转化为图论问题了!

再观察这个问题的性质:由于对角线的和不为 $0$,那么存在至少一个点有自环。如果从 $i$ 到 $j$ 存在一条长度为 $k$ 且经过有自环的点,那么我们一定通过不断走自环可以得到长度为 $k+1,k+2,\dots​$ 的路径。

这就意味着如果存在 $k$,那么一定所有点都可达

直接用 $01$ 矩阵建立有向图,使用 $\text{Tarjan}$ 求出强连通分量的个数是否为 $1$ 即可。

时间复杂度:$O(n^2)$


Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <cstdio>
#include <algorithm>
#include <stack>
#define fail puts("NO"),exit(0)

const int N=2e3+5,M=N*N;
int n,idx,cnt,tot,lnk[N],ter[M],nxt[M],dfn[N],low[N];
bool vis[N];
std::stack<int> st;

void add(int u,int v) {
ter[++tot]=v,nxt[tot]=lnk[u],lnk[u]=tot;
}
void tarjan(int u) {
dfn[u]=low[u]=++idx,st.push(u),vis[u]=1;
for(int i=lnk[u];i;i=nxt[i]) {
int v=ter[i];
if(!dfn[v]) {
tarjan(v);
low[u]=std::min(low[u],low[v]);
} else {
if(vis[v]) low[u]=std::min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u]) {
if(++cnt>1) fail;
do {
vis[u=st.top()]=0,st.pop();
} while(dfn[u]!=low[u]);
}
}
int main() {
scanf("%d",&n);
for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) {
int x;
scanf("%d",&x);
if(x&&i!=j) add(i,j);
}
tarjan(1);
for(int i=1;i<=n;++i) if(!dfn[i]) fail;
puts("YES");
return 0;
}
0%