染色
Problem:1300
Time Limit:1000ms
Memory Limit:65535K
Description
给你一棵有n个顶点的有根树。顶点编号从1到n,根是顶点编号1。每个顶点都有一个颜色,让我们用Cv来表示顶点v的颜色。最初Cv = 0。您必须使用尽可能少的步骤将树着色为给定的颜色。在每个步骤中,您可以选择一个顶点v和颜色x,然后将顶点v的子树(包括v)全部染成颜色x。
Input
第一行输入一个整数 N(2<=N<=1e5)代表树的顶点的个数,所有 N 之和小于1e6。 第二行包含 N - 1 个整数 P2 ,P3 ... ,Pn(1<=Pi<i),其中 Pi 代表树的一条边 i 与 pi 第三行包含 N 个整数,C1,C2....Cn (0<=Ci<=N) Ci 代表要求把顶点 i 染成的颜色
Output
输出一个整数,将树着色为给定的颜色,必须执行的最小步数。
Sample Input
6 1 2 2 1 5 2 1 1 1 1 1 7 1 1 2 3 1 4 3 3 1 1 1 2 3
Sample Output
3 5
题意:中文题。
思路:用dfs模拟一下染色的过程,如果子节点和父亲节点不相同就+1就行了。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
struct node
{
vector<int> next;
}q[100005];
int c[100005];
int a[100005];
int cnt;
void dfs(int fa,int pos,int col)
{
a[pos]=col;
if(a[pos]!=c[pos])
{
a[pos]=c[pos];
cnt++;
}
int len=q[pos].next.size();
for(int i=0;i<len;i++)
{
if(q[pos].next[i]!=fa)
dfs(pos,q[pos].next[i],c[pos]);
}
}
int main()
{
int n,x;
while(~scanf("%d",&n))
{
memset(q,0,sizeof(q));
memset(a,0,sizeof(a));
cnt=0;
for(int i=2;i<=n;i++)
{
scanf("%d",&x);
q[i].next.push_back(x);
q[x].next.push_back(i);
}
for(int i=1;i<=n;i++)
{
scanf("%d",&c[i]);
}
dfs(0,1,0);
printf("%d\n",cnt);
}
return 0;
}