Codeforces Round #236 (Div. 2) E. Strictly Positive Matrix 强连通
题目大概意思是给定一个矩阵A,每个元素都非负,主对角线上元素大于0,问是否存在常数k,使得A的k次幂的每个元素都大于0。
由A的k次幂联想到离散数学中的可达性矩阵,即问是否存在常数k,使得任意两点之间都存在长度为k的路径,因为主对角线上严格大于0,也就是说有自环,所以只要该图是强联通的即可满足,因为若任意两点之间都能走到,那么配合自环就能找到一个共同的长度k。
#include<cstdio> #include<algorithm> #include<vector> #include<cstring> #include<stack> using namespace std; const int maxn = 2000 + 10; vector<int> G[maxn], G2[maxn]; vector<int> S; int vis[maxn], sccno[maxn], scc_cnt; int max(int a,int b) { if(a>b) return a; else return b; } void dfs1(int u) { if(vis[u]) return; vis[u] = 1; for(int i = 0; i < G[u].size(); i++) dfs1(G[u][i]); S.push_back(u); } void dfs2(int u) { if(sccno[u]) return; sccno[u] = scc_cnt; for(int i = 0; i < G2[u].size(); i++) dfs2(G2[u][i]); } void find_scc(int n) { int i; scc_cnt = 0; S.clear(); memset(sccno, 0, sizeof(sccno)); memset(vis, 0, sizeof(vis)); for(i = 0; i < n; i++) dfs1(i); for(i = n-1; i >= 0; i--) if(!sccno[S[i]]) { scc_cnt++; dfs2(S[i]); } } int main() { int i,j; int n,x; scanf("%d",&n); for(i=0;i<n;i++) for(j=0;j<n;j++) { scanf("%d",&x); if(x!=0) { G[i].push_back(j); G2[j].push_back(i); } } find_scc(n); if(scc_cnt==1) printf("YES\n"); else printf("NO\n"); return 0; }