You have matrix a of size n × n. Let's number the rows of the matrix from 1 to n from top to bottom, let's number the columns from 1 to nfrom left to right. Let's use aij to represent the element on the intersection of the i-th row and the j-th column.
Matrix a meets the following two conditions:
- for any numbers i, j (1 ≤ i, j ≤ n) the following inequality holds: aij ≥ 0;
- .
Matrix b is strictly positive, if for any numbers i, j (1 ≤ i, j ≤ n) the inequality bij > 0 holds. You task is to determine if there is such integer k ≥ 1, that matrix ak is strictly positive.
The first line contains integer n (2 ≤ n ≤ 2000) — the number of rows and columns in matrix a.
The next n lines contain the description of the rows of matrix a. The i-th line contains n non-negative integers ai1, ai2, ..., ain (0 ≤ aij ≤ 50). It is guaranteed that .
If there is a positive integer k ≥ 1, such that matrix ak is strictly positive, print "YES" (without the quotes). Otherwise, print "NO" (without the quotes).
2 1 0 0 1
NO
5 4 5 6 1 2 1 2 3 4 5 6 4 1 2 4 1 1 1 1 1 4 4 4 4 4
YES
题意:给出一个矩阵,求该矩阵是否存在一个K。他的K次幂的每个元素都大于0
思路:图的邻接矩阵表示点与点的可达性。a^k中a[i][j]>0表示存在长度为K的路径从I到J。由题可知,a^k每个元素都大于0,任意两点可达,是个有向完全图。要求a矩阵必须只有一个强连通分量。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define maxn 2200 #define maxm 4008000 int key[maxn][maxn]; int first[maxn],low[maxn],dfn[maxn],vis[maxn],c[maxn],s[maxn]; int vv[maxm],nxt[maxm]; int e,t,cnt,p; void addEdge(int u,int v) { vv[e] = v; nxt[e] = first[u]; first[u] = e++; } inline int min(int a,int b) { return a>b?b:a; } void Tarjan(int u) { dfn[u] = low[u] = ++cnt; s[++p] = u; vis[u] = 1; for(int i = first[u];i != -1;i = nxt[i]){ int v = vv[i]; if(!dfn[v]){ Tarjan(v); low[u] = min(low[u],low[v]); } else if(vis[v]) low[u] = min(low[u],dfn[v]); } if(low[u] == dfn[u]){ ++t; while(s[p] != u){ vis[s[p]] = 0; c[s[p]] = t; p--; } c[s[p]] = t; p--; } } int main() { int n; while(scanf("%d",&n)!=EOF){ e = cnt = t = p = 0; memset(vis,0,sizeof(vis)); memset(dfn,0,sizeof(dfn)); memset(first,-1,sizeof(first)); for(int i = 1;i <= n;i++) for(int j = 1;j <= n;j++){ scanf("%d",&key[i][j]); if(i != j && key[i][j] > 0) addEdge(i,j); } for(int i = 1;i <= n;i++) if(!dfn[i]) Tarjan(i); int fuck = c[1]; bool flag = true; for(int i = 1;i <= n;i++){ if(c[i] != fuck){ flag = false; break; } } if(flag) printf("YES\n"); else printf("NO\n"); } return 0; }