Strictly Positive Matrix
题目描述:
题目大概讲的是,输入一个n*n大小的矩阵,然后问我们是否存在一个正整数k,使得这个矩阵的k次幂内的元素不含有0。
题目分析:
由于这个题目给定的n最大为2000,因此不能使用矩阵乘法,然后可能很多人会以为这个题目与线性代数的某些定理有关。
其实这个题目与线性代数并没有关系,反而涉及到离散数学的布尔积,二元关系的传递性知识相关,我们可以这样认为,如果矩阵第i行第j列的元素大于0的话,那么我们认为第i个结点与第j个结点可以连通,否则就认为不能连通。然后问题就转化为n个结点的强连通分量是否为1的问题,如果为1的话,那么输出YES,否则输出NO。
至于为什么强连通分量内的任意两个点为什么能够互相到达,这是因为这个矩阵的幂是肯定可以是这两个点互相连通的。
代码:
#include <iostream>
#include <cstdio>
#include <stdio.h>
#include <cstdlib>
#include <stdlib.h>
#include <cmath>
#include <math.h>
#include <algorithm>
#include <string>
#include <cstring>
#include <string.h>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#define reg register
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
#define lowbit(x) (x&(-x))
using namespace std;
const int Maxn=2005;
int tot,tt,n;
int dfn[Maxn],low[Maxn],num[Maxn];
int a[Maxn][Maxn];
stack <int> s;
void dfs(int x)
{
dfn[x]=low[x]=(++tot);
s.push(x);
for (reg int i=1;i<=n;i++)
if (a[x][i])
{
if (!dfn[i])
{
dfs(i);
low[x]=min(low[x],low[i]);
continue;
}
low[x]=min(low[x],dfn[i]);
}
if (dfn[x]==low[x])
{
int temp;
tt++;
do
{
temp=s.top();
num[temp]=tt;
s.pop();
} while (temp!=x);
}
}
void Tarjan()
{
tot=tt=0;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
for (reg int i=1;i<=n;i++)
if (!dfn[i]) dfs(i);
}
int main()
{
scanf("%d",&n);
for (reg int i=1;i<=n;i++)
{
for (reg int j=1;j<=n;j++) scanf("%d",&a[i][j]);
}
Tarjan();
for (reg int i=2;i<=n;i++)
if (num[i]!=num[1])
{
printf("NO\n");
return 0;
}
printf("YES\n");
return 0;
}