Strictly Positive Matrix

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

猜你喜欢

转载自blog.csdn.net/qq_36679229/article/details/88609185