染色
https://www.acwing.com/problem/content/4493/
题意就是给你每个点的父节点的编号,初始颜色是0,然后把每个点颜色给你,每一次染色都可以把其及其子树染成和它一样的,问变成对应的颜色至少需要操作多少次
树啥的好像没有我想的那么复杂...
我也不清楚,还是多做做题然后思考思考吧
这个题我还是有点想复杂了
这个题有两种做法:
不建树:
因为每个根节点(父节点)染色,对应的子树颜色都是一样的,如果遍历到某个点的颜色和父节点的颜色不同,就需要操作一次(这是必然的)
就虽然没有实现染色的这个操作,但事实上,染过色之后子树和根节点的颜色是一样的,但现在不一样了,说明需要执行一次操作了
#include<iostream> using namespace std; const int N=2e6+10; int p[N],c[N]; int main(){ int n; cin>>n; for(int i=2;i<=n;i++) cin>>p[i]; for(int i=1;i<=n;i++) cin>>c[i]; int res=0; for(int i=1;i<=n;i++)//遍历每个点,看看每个点的颜色和父节点的颜色是否一样 { if(c[i]!=c[p[i]]) res++; } cout<<res<<"\n"; return 0; }
建树:
#include<iostream> #include<cstring> using namespace std; const int N=2e6+10; int h[N],e[N],ne[N],idx,c[N]; void add(int a,int b) { e[idx]=b; ne[idx]=h[a]; h[a]=idx++; } int dfs(int u,int w) { int res=(c[u]!=w); for(int i=h[u];i!=-1;i=ne[i]) { int j=e[i]; res+=dfs(j,c[u]); } return res; } int main(){ memset(h,-1,sizeof(h)); int n; cin>>n; for(int i=2;i<=n;i++) { int p; cin>>p; add(p,i);//树是有向图 } for(int i=1;i<=n;i++) cin>>c[i]; cout<<dfs(1,0); return 0; }
                
            
        
浙公网安备 33010602011771号