题意
给定一个 n∗n 的矩阵 A,每个元素都非负判断是否存在一个整数 k 使得 A^k 的所有元素 >0 n≤2000(矩阵中[i][i]保证为1)
题解
此题本质上就是问根据所给矩阵建图,是否全图为一个强联通分量。
所以就很简单了
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 const int N=3000; 8 int cnt,head[N]; 9 int dfn[N],low[N],stack[N],top,tot,vis[N],num,c[N]; 10 int n; 11 struct edge{ 12 int to,nxt; 13 }e[5000000]; 14 void add(int u,int v){ 15 cnt++; 16 e[cnt].nxt=head[u]; 17 e[cnt].to=v; 18 head[u]=cnt; 19 } 20 void Tarjan(int u){ 21 dfn[u]=low[u]=++tot; 22 stack[++top]=u; 23 vis[u]=1; 24 for(int i=head[u];i;i=e[i].nxt){ 25 int v=e[i].to; 26 if(dfn[v]==0){ 27 Tarjan(v); 28 low[u]=min(low[u],low[v]); 29 } 30 else if(vis[v])low[u]=min(low[u],dfn[v]); 31 } 32 if(dfn[u]==low[u]){ 33 int x; 34 num++; 35 do{ 36 x=stack[top--]; 37 c[x]=num; 38 vis[x]=0; 39 }while(u!=x); 40 } 41 } 42 int main(){ 43 scanf("%d",&n); 44 for(int i=1;i<=n;i++) 45 for(int j=1,a;j<=n;j++){ 46 scanf("%d",&a); 47 if(i==j||a==0)continue; 48 add(i,j); 49 } 50 for(int i=1;i<=n;i++){ 51 if(dfn[i]==0)Tarjan(i); 52 } 53 for(int i=1;i<=n;i++){ 54 // cout<<c[i]<<endl; 55 if(c[i]>1){ 56 printf("NO"); 57 return 0; 58 } 59 } 60 printf("YES"); 61 return 0; 62 }