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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值