CQOI2009 叶子的染色
树里的定义:叶子节点(1-n)没有后继节点。
然后树形DP
dp[r][0]+=min(dp[x][0]-1,min(dp[x][1],dp[x][2])); dp[r][1]+=min(dp[x][1]-1,min(dp[x][0],dp[x][2])); dp[r][2]+=min(dp[x][0],min(dp[x][1],dp[x][2]));
初始化
叶子 dp[r][c[r]]=1;dp[r][2]=dp[r][1^c[r]]=inf; 非叶子 dp[r][0]=dp[r][1]=1;dp[r][2]=0;
代码:
#include<bits/stdc++.h> using namespace std; const int N=1e4+33; #define ll long long const ll inf=1e9; ll c[N],dp[N][3],tot,f[N],sum[N],root,n,m; struct re{ int v; int nex; }; re e[N*2]; void dfs(int r,int fath){ bool az=1; for(int i=f[r];i;i=e[i].nex){ int x=e[i].v; if(x==fath)continue; dfs(x,r); az=0; } if(az){dp[r][c[r]]=1;dp[r][2]=dp[r][1^c[r]]=inf;return;} dp[r][0]=dp[r][1]=1; dp[r][2]=0; for(int k=f[r];k;k=e[k].nex){ int x=e[k].v; if(x==fath)continue; dp[r][0]+=min(dp[x][0]-1,min(dp[x][1],dp[x][2])); dp[r][1]+=min(dp[x][1]-1,min(dp[x][0],dp[x][2])); dp[r][2]+=min(dp[x][0],min(dp[x][1],dp[x][2])); } } int main() { //freopen("p.in","r",stdin); cin>>m>>n; for(int i=1;i<=n;i++)cin>>c[i]; for(int i=1;i<=m-1;i++) { int a,b; cin>>a>>b; sum[a]++;sum[b]++; tot++; e[tot].v=b; e[tot].nex=f[a]; f[a]=tot; tot++; e[tot].v=a; e[tot].nex=f[b]; f[b]=tot; } for(int i=1;i<=m;i++)if(sum[i]>1){root=i;break;} int ywx; dfs(root,-1); cout<<min(min(dp[root][0],dp[root][1]),dp[root][2]); return 0; }
ARC101F