Hướng dẫn giải của Atcoder Educational DP Contest P - Independent Set


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Độ phức tạp thời gian: ~O(N)~

Đầu tiên, chọn một đỉnh bất kỳ làm gốc, gọi đỉnh đó là ~root~. Gọi ~dp[i][j]~ là số cách để tô màu cây con của đỉnh ~i~, với đỉnh ~i~ được tô màu ~j~.

Chúng ta sẽ coi ~j=0~ là màu đen và ~j=1~ là màu trắng.

Nếu chúng ta tô đỉnh ~i~ màu đen, thì toàn bộ các con của nó phải màu trắng. Do đó, ta có: ~dp[i][0] = \prod _{c \in C[u]} dp[c][1]~ (~C[u]~ là tập các con của u).

Nếu chúng ta tô đỉnh ~i~ màu trắng, thì các con của nó có thể có màu đen hoặc trắng đều được. Do đó, ta có: ~dp[i][1]=\prod _{c \in C[u]} (dp[c][0]+dp[c][1])~

Đáp án sẽ là ~dp[root][0]+dp[root][1]~

Code

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1e5;
const int MOD = 1e9 + 7;

int add(int i, int j) {
    if ((i += j) >= MOD)
        i -= MOD;
    return i;
}
int mul(int i, int j) {
    return int((long long) i * j % MOD);
}

vector<int> adj[MAXN];
int dp[MAXN][2];

void dfs(int i, int p) {
    dp[i][0] = dp[i][1] = 1;
    for (int j : adj[i]) if (j != p) {
        dfs(j, i);
        dp[i][0] = mul(dp[i][0], dp[j][1]);
        dp[i][1] = mul(dp[i][1], add(dp[j][0], dp[j][1]));
    }
}

int main() {
    cin.tie(0)->sync_with_stdio(0);

    int n;
    cin >> n;
    for (int i = 0, a, b; i + 1 < n; ++i) {
        cin >> a >> b;
        --a;
        --b;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }
    dfs(0, 0);
    cout << add(dp[0][0], dp[0][1]) << '\n';
}

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.