CodeForces - 402E Strictly Positive Matrix(tarjan求連通分量個數)
阿新 • • 發佈:2021-01-20
題目大意:
給出一個矩陣a,滿足\(a_{ij} \geq 0\)且\(\sum_{i=1}^n a_{ii} > 0\),問是否存在k使得\(a^k\)為一個嚴格正矩陣。
若b為嚴格正矩陣則滿足任意的\(b_{ij} > 0\)。
思路:
題目滿足a中元素都是非負的,結合矩陣乘法的性質可以發現,我們並不關心a矩陣中具體的數值,只關心它是否為0,考慮將a矩陣轉換為一個01矩陣。由01矩陣聯想到鄰接矩陣,對於某一個鄰接矩陣D,如果 \(d_{i,j}=1\) 則表示i,j間有一條邊,那麼嚴格正矩陣的含義就是任意的兩點都存在一條邊,就可以使用tarjan來求連通分量個數進行判斷。
Code:
#include <bits/stdc++.h> using namespace std; const int N = 2010; const int INF = 0x3f3f3f3f; struct Node { int to, next; } e[N * N * 2]; int head[N], tot; int dfn[N], low[N], num; int col; bool isIns[N]; int st[N], top; int n; bool mp[N][N], hasZero; void add_edge(int u, int v) { e[++tot].to = v; e[tot].next = head[u]; head[u] = tot; } void tarjan(int u) { dfn[u] = low[u] = ++num; isIns[u] = 1; st[++top] = u; for (int i = head[u]; ~i; i = e[i].next) { int v = e[i].to; if (!dfn[v]) { tarjan(v); low[u] = min(low[u], low[v]); } else if (isIns[v]) { low[u] = min(low[u], dfn[v]); } } if (low[u] == dfn[u]) { ++col; while (st[top] != u) { isIns[st[top--]] = 0; } isIns[st[top--]] = 0; } } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); memset(head, -1, sizeof(head)); cin >> n; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { int t; cin >> t; if (t) mp[i][j] = 1; else hasZero = 1; } } if (!hasZero) { cout << "YES" << endl; return 0; } for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (mp[i][j]) add_edge(i, j); for (int i = 1; i <= n; i++) if (!dfn[i]) tarjan(i); if (col == 1) cout << "YES" << endl; else cout << "NO" << endl; return 0; }