叶子的染色
给定各叶子要求的最终着色颜色,给节点黑白着色
正文
/*
原题:叶子的染色(一本通 5.2 练习4)
题意:给定各叶子要求的最终着色颜色,给节点黑白着色使每条根到叶路径都含一个有色点且其最后有色点颜色符合,求最少着色数。
思路:选度数>1 的节点作根。五态树形 DP:0 黑、1 白、2 未涂且需祖先黑、3 未涂且需祖先白、4 未涂且已自满足。叶子按固定色取初值,根不可用 2/3。
复杂度:O(m) 时间,O(m) 空间。
易错点:叶子颜色是“路径最后有色点”的颜色而非叶子必须涂;合并儿子时黑/白要求冲突则不可行;必须根在内部节点。
*/
#include <bits/stdc++.h>
using namespace std;
const int M=10005;
const int INF=1e9;
int m,n;
vector<int> g[M];
int col[M];
int dp[M][5];
void dfs(int u,int fa){
vector<int> ch;
for(int v:g[u])
if(v!=fa)ch.push_back(v);
if(u>=1&&u<=n&&ch.empty()){
dp[u][0]=(col[u]==0?1:INF);
dp[u][1]=(col[u]==1?1:INF);
dp[u][2]=(col[u]==0?0:INF);
dp[u][3]=(col[u]==1?0:INF);
dp[u][4]=INF;
return;
}
for(int v:ch)dfs(v,u);
dp[u][0]=1;
dp[u][1]=1;
for(int v:ch){
dp[u][0]+=min({dp[v][0],dp[v][1],dp[v][2],dp[v][4]});
dp[u][1]+=min({dp[v][0],dp[v][1],dp[v][3],dp[v][4]});
}
long long bsat=0,bblk=INF,bwht=INF;
for(int v:ch){
long long sat=min({(long long)dp[v][0],(long long)dp[v][1],(long long)dp[v][4]});
long long blk=dp[v][2];
long long wht=dp[v][3];
long long nbsat=INF,nbblk=INF,nbwht=INF;
if(bsat<INF){
nbsat=min(nbsat,bsat+sat);
nbblk=min(nbblk,bsat+blk);
nbwht=min(nbwht,bsat+wht);
}
if(bblk<INF){
nbsat=min(nbsat,bblk+sat);
nbblk=min(nbblk,bblk+blk);
}
if(bwht<INF){
nbwht=min(nbwht,bwht+sat);
nbwht=min(nbwht,bwht+wht);
}
bsat=nbsat;
bblk=nbblk;
bwht=nbwht;
}
dp[u][4]=bsat;
dp[u][2]=bblk;
dp[u][3]=bwht;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>m>>n;
for(int i=1;i<=n;i++)cin>>col[i];
for(int i=1;i<m;i++){
int a,b;
cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
int root=1;
for(int i=1;i<=m;i++)
if((int)g[i].size()>1){
root=i;
break;
}
if(g[root].size()<=1){
if(m==1){cout<<1<<"\n";return 0;}
if(m==2){cout<<(col[1]==col[2]?1:2)<<"\n";return 0;}
}
dfs(root,-1);
cout<<min({dp[root][0],dp[root][1],dp[root][4]})<<"\n";
return 0;
}
一本通·提高篇的其它内容
- 活动安排
- 种树
- 喷水装置
- 加工生产调度
- 智力大冲浪
- 数列极差
- 数列分段
- 线段
- 家庭作业
- 钓鱼
- 糖果传递
- 愤怒的牛
- Best Cow Fences
- 曲线
- 数列分段 II
- 扩散
- 灯泡
- 传送带
- 数的划分
- 生日蛋糕
- 小木棍
- Addition Chains
- 埃及分数
- 平板涂色
- 质数方阵
- 靶形数独
- 电路维修
- 魔板
- Knight Moves
- 棋盘游戏
- Keyboarding
- 移动玩具
- 山峰和山谷
- Oulipo
- 图书管理
- Power Strings
- Seekthe Name, Seek the Fame
- Friends
- A Horrible Poem
- Beads
- Antisymmetry
- 门票
- 收集雪花
- 剪花布条
- Power Strings
- Radio Transmission
- OKR-Periods of Words
- 似乎在梦中见过的样子
- Censoring
- Phone List
- The XOR Largest Pair
- Nikitosh 和异或
- Immediate Decodability
- L 语言
- Secret Message 秘密信息
- 背单词
- The Xor-longest Path
- Keywords Search
- 玄武密码
- Censoring