Independent Sets in Tree
2020-1νκΈ°, λνμμ βμκ³ λ¦¬μ¦β μμ μ λ£κ³ 곡λΆν λ°λ₯Ό μ 리ν κΈμ λλ€. μ§μ μ μΈμ λ νμμ λλ€ :)
κ·Έλν $G$μμ <Independent Set; λ 립μ§ν©>μ μλμ κ°μ΄ μ μνλ€.
Definition. Independent Set
Given a graph $G = (V, E)$, a subset $S \subset V$ is an <independent set> if there are no edges between nodes in the subset $S$.
<Independent Set Problem>μ κ·Έλνμμ κ°λ₯ν λ 립μ§ν© μ€ κ°μ₯ ν° μ§ν©μ μ°Ύλ λ¬Έμ λ₯Ό λ§νλ€. μΌλ°μ μΌλ‘ <Independent Set Problem>λ₯Ό polynomial timeμΌλ‘ νΈλ κ²μ λΆκ°λ₯νλ€. μ΄κ²μ λν΄μλ <NP-complete>μ λν΄ λ€λ£° λ λ€μ μΈκΈνλλ‘ νκ² λ€.
κ·Έλ¬λ λ§μ½ κ·Έλν $G$κ° treeλΌλ©΄, <Independent Set Problem>λ₯Ό linear timeμΌλ‘ ν΄κ²°ν μ μλ€!!
λ¨Όμ 첫 λ²μ§Έ κ²½μ°λ νΈλ¦¬μ λ Έλμ κ°μ€μΉκ° μλ κ²½μ°λ€. λ¬Έμ λ₯Ό λ¬μ¬νλ©΄ μλμ κ°λ€.
λΉμ μ νμ¬ νν°λ₯Ό μ£Όμ΅νλ € νλ€. μ΅λν λ§μ μ¬λμ μ΄λνλ € νμ§λ§ κ°κ°μ μ¬λλ€μ λ°λ‘ μ§μ μμ¬κ° νν°μ μ¬ κ²½μ° νν°μ μ€μ§ μλλ€.
μ΄ κ²½μ°, greedy νκ² μ κ·Όνμ¬ λ¬Έμ λ₯Ό ν΄κ²°ν μ μλ€!
while $T$ is not empty:
ββ take all the leaves to the solution.
ββ remove them and their parents from $T$.
return the constructed solution.
λ λ²μ§Έ κ²½μ°λ νΈλ¦¬μ λ Έλμ κ°μ€μΉκ° μ‘΄μ¬νλ κ²½μ°λ€. λ¬Έμ λ₯Ό λ¬μ¬νλ©΄,
μμ λ¬Έμ μ μν©μ λκ°μΌλ νν°μ μ€λ μ¬λλ§λ€ 맀λ ₯μ μΈ μ λκ° μμ΄μ μ΄ λ§€λ ₯λμ εμ μ΅λλ‘ νκ³ μ νλ€.
μ΄ κ²½μ°λ DPλ₯Ό ν΅ν΄ λ¬Έμ λ₯Ό ν΄κ²°ν μ μλ€!!
λ Έλ $s$λ₯Ό rootλ‘ νλ sub-treeμ Maximum Weight Ind. Setμ μλμ κ°μ΄ ꡬν μ μλ€.
\[D(s) = \max \left\{ \sum_{\text{child $v$ of $s$}} D(v), \; w(s) + \sum_{\text{grandchild $u$ of $s$}} D(u) \right\}\]ꡬν
λ²‘μ€ 2213λ²: νΈλ¦¬μ λ 립μ§ν©λ₯Ό κΈ°μ€μΌλ‘ ꡬνν μ½λλ₯Ό ν΄μ€ν΄λ³΄κ² λ€.
λ¨Όμ Maximum Weight Sum of Ind. Set $D(u)$μ κ°μ μ μ₯ν DP λ°°μ΄μ ꡬμνλ€.
int dp[VMAX][2]; // Maximum Weight Sum of Ind. Set
μ΄λ, dp[i][0]
λ $i$λ²μ§Έ λ
Έλλ₯Ό ν¬ν¨νμ§ μμμ λ, dp[i][1]
λ $i$λ²μ§Έ λ
Έλλ₯Ό ν¬ν¨νμ λμ Maximum Weight Sumμ΄λ€.
λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν μ¬κ·ν¨μλ μλμ κ°λ€.
int root = 1; // μ΄λ λ
Έλλ₯Ό rootλ‘ μ¬μ©νλ μκ΄ X
travel(root, -1);
void travel(int node, int par) {
dp[node][0] = 0;
dp[node][1] = weight[node];
IndSet[node][1].push_back(node);
// visit children
for (int i = 0; i < edges[node].size(); i++) {
int child = edges[node][i];
if (child == par) continue; // root node
travel(child, node); // recursion
// exclude root node -> use child or not -> use `dp[child][0]` or `dp[child][1]`
bool whichBigger = dp[child][1] >= dp[child][0];
dp[node][0] += dp[child][whichBigger];
for (int j = 0; j < IndSet[child][whichBigger].size(); j++) {
IndSet[node][0].push_back(IndSet[child][whichBigger][j]);
}
// include root node -> not use child -> use `dp[child][0]`
dp[node][1] += dp[child][0];
for (int j = 0; j < IndSet[child][0].size(); j++) {
IndSet[node][1].push_back(IndSet[child][0][j]);
}
}
}
travel(int node, int par)
ν¨μλ dp[node][]
μ κ°μ κ²°μ νλ ν¨μλ‘ μμ λ
Έλλ€μ dp
κ°μ μννλ€. λ¬Έμ μμ λ
립μ§ν©μ μνλ μμμ λͺ©λ‘μ μ μνλΌλ μ‘°κ±΄μ΄ μμ΄ IndSet
μΌλ‘ μ΄λ₯Ό κΈ°λ‘νμλ€.
dp[node][]
μ κ°μ κ°±μ ν λλ λ κ°μ§ κ²½μ°κ° μλλ°,
1. node
λ₯Ό ν¬ν¨νμ§ μλ κ²½μ°; dp[node][0]
μ΄ κ²½μ° dp[child][0]
κ³Ό dp[child][1]
μ€ λ ν° κ°μ μ ννλ©΄ λλ€. μ²μ μ½λλ₯Ό 지 λλ dp[child][1]
λ₯Ό μ ννλλ‘ νλλ°, μ΄κ²μ child
λ
Έλλ₯Ό λ°λμ μ ννκ² νλ€. κ·Έλ¬λ child
μ ννλ κ²μ΄ κ°μ€ν©μ μ΅λλ‘ νλ€λ 보μ₯μ΄ μκΈ° λλ¬Έμ dp[child][0]
κ³Ό dp[child][1]
μ κ°μ λΉκ΅νμ¬ λ ν° κ°μ μ νν΄μ€μΌ νλ€!
2. node
λ₯Ό ν¬ν¨νλ κ²½μ°; dp[node][1]
μ΄ κ²½μ°λ κ°λ¨νκ² dp[child][0]
μ κ°μ λν΄μ£Όλ©΄ λλ€. π
μμ κ°μ΄ μ½λλ₯Ό μ§λ©΄ λ¬Έμ λ₯Ό ν΄κ²°ν μ μλ€.
(μ°Έκ³ λ‘ λ³ΈμΈμ λ§μ§λ§μ sorting 쑰건μ μμ΄μ λͺλ²μ μ€ν¨νμλ€β¦ π€―)
βνΈλ¦¬μ λ 립μ§ν©β λ¬Έμ μ κ²½μ° ν¬μ€νΈλ₯Ό μμ±νλ©΄μ λ€μ νμ΄λ³΄μλλ°, νμ€ν μ λ²μ λΉν΄ μ½λ© μ€νμΌμ΄ λ§μ΄ λ€λ¬μ΄μ‘λ€. π