题目:[CQOI2009]叶子的染色
分析:
根可以随便选一个非叶子结点。 dp[u][k]表示u结点染成k色使得u子树合法的最小染色数。 可以想到如果u的孩子v染了k色,那么v的k色完全可以染在u上,不需要染v。可以得到转移方程:
代码:
#include <bits/stdc++.h>
using namespace std
;
typedef long long ll
;
#define print(i) cout << "debug: " << i << endl
#define close() ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define mem(a, b) memset(a, b, sizeof(a))
#define pb(a) push_back(a)
#define x first
#define y second
typedef pair
<int, int> par
;
const ll mod
= 1e9 + 7;
const int maxn
= 1e6 + 10;
const int inf
= 0x3f3f3f3f;
int leaf
[maxn
];
vector
<int> g
[maxn
];
int dp
[maxn
][2];
void dfs(int u
, int fa
)
{
if(g
[u
].size() == 1)
{
dp
[u
][leaf
[u
]] = 1, dp
[u
][!leaf
[u
]] = inf
;
return;
}
dp
[u
][0] = dp
[u
][1] = 1;
for(int v
: g
[u
])
{
if(v
== fa
) continue;
dfs(v
, u
);
dp
[u
][0] += min(dp
[v
][0] - 1, dp
[v
][1]);
dp
[u
][1] += min(dp
[v
][1] - 1, dp
[v
][0]);
}
}
int main()
{
int n
, m
; cin
>> n
>> m
;
for(int i
= 1; i
<= m
; i
++) cin
>> leaf
[i
];
for(int i
= 1; i
< n
; i
++)
{
int a
, b
; cin
>> a
>> b
;
g
[a
].pb(b
), g
[b
].pb(a
);
}
dfs(n
, -1);
cout
<< min(dp
[n
][0], dp
[n
][1]) << endl
;
}
转载请注明原文地址: https://lol.8miu.com/read-24054.html