CF402E Strictly Positive Matrix 題解 tarjan強連通分量

題目鏈接:http://codeforces.com/problemset/problem/402/E

題目大意:

給出一個矩陣 \(A\),問是否存在一個正整數 \(k\) 使得 \(A^k\) 的所有元素都是正數。

解題思路:

根據矩陣的性質,\(A^k_{i,j} \gt 0\) 當且僅當 \(i\)\(j\) 存在一條可行路徑。

所以可以把矩陣轉成圖論模型,若 \(A_{i,j} \gt 0\),則從 \(i\)\(j\) 連一條有向邊。

如果所有點處在同一個強連通分量,則爲 "YES";否則,爲 "NO"。

示例程序:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2020;
int n, a, dfn[maxn], low[maxn], id[maxn], ts, scc;
bool ins[maxn];
vector<int> g[maxn];
stack<int> stk;

void tarjan(int u) {
    dfn[u] = low[u] = ++ts;
    stk.push(u), ins[u] = true;
    for (auto v : g[u]) {
        if (!dfn[v])
            tarjan(v), low[u] = min(low[u], low[v]);
        else if (ins[v])
            low[u] = min(low[u], dfn[v]);
    }
    if (dfn[u] == low[u]) {
        scc++;
        int v;
        do {
            v = stk.top(); stk.pop();
            ins[v] = false;
            id[v] = scc;
        } while (v != u);
    }
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            scanf("%d", &a);
            if (a && i != j) g[i].push_back(j);
        }
    }
    tarjan(1);
    for (int i = 1; i <= n; i++) {
        if (id[i] != 1) {
            puts("NO");
            return 0;
        }
    }
    puts("YES");
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章