Day2-O-Coloring a Tree CodeForces-902B

You are given a rooted tree with n vertices. The vertices are numbered from 1 to n, the root is the vertex number 1.

Each vertex has a color, let's denote the color of vertex v by cv. Initially cv = 0.

You have to color the tree into the given colors using the smallest possible number of steps. On each step you can choose a vertex v and a color x, and then color all vectices in the subtree of v (including v itself) in color x. In other words, for every vertex u, such that the path from root to u passes through v, set cu = x.

It is guaranteed that you have to color each vertex in a color different from 0.

You can learn what a rooted tree is using the link: https://en.wikipedia.org/wiki/Tree_(graph_theory).

Input

The first line contains a single integer n (2 ≤ n ≤ 104) — the number of vertices in the tree.

The second line contains n - 1 integers p2, p3, ..., pn (1 ≤ pi < i), where pi means that there is an edge between vertices i and pi.

The third line contains n integers c1, c2, ..., cn (1 ≤ ci ≤ n), where ci is the color you should color the i-th vertex into.

It is guaranteed that the given graph is a tree.

Output

Print a single integer — the minimum number of steps you have to perform to color the tree into given colors.

Examples

Input
6
1 2 2 1 5
2 1 1 1 1 1
Output
3
Input
7
1 1 2 3 1 4
3 3 1 1 1 2 3
Output
5

(图片好像挂了,具体Note可以看一下原题)

思路:从树根1开始,层序遍历涂色,DFS+BFS,代码如下:

const int maxm = 1e4+10;

int color[maxm], now[maxm], n, tmp, t;
vector<int> son[maxm];

void dfs(int i, int col) {
    for(auto j : son[i])
        dfs(j, col);
    now[i] = col;
}

int main() {
    scanf("%d", &n);
    for (int i = 2; i <= n; ++i) {
        scanf("%d", &tmp);
        son[tmp].push_back(i);
    }
    for (int i = 1; i <= n; ++i)
        scanf("%d", &color[i]);
    queue<int> q;
    q.push(1);
    while(!q.empty()) {
        tmp = q.front(), q.pop();
        if(color[tmp] != now[tmp]) {
            dfs(tmp, color[tmp]);
            ++t;
        }
        for(auto i : son[tmp])
            q.push(i);
    }
    printf("%d
", t);
    return 0;
}
View Code

DFS版层序,代码如下:

const int maxm = 1e4 + 10;

int color[maxm], now[maxm], n, tmp, t;
vector<int> son[maxm];

void dfs1(int i, int col) {
    for(auto j : son[i])
        dfs1(j, col);
    now[i] = col;
}

void dfs2(int i) {
    if(color[i] != now[i]) {
        dfs1(i, color[i]);
        ++t;
    }
    for(auto j : son[i])
        dfs2(j);
}

int main() {
    scanf("%d", &n);
    for (int i = 2; i <= n; ++i) {
        scanf("%d", &tmp);
        son[tmp].push_back(i);
    }
    for (int i = 1; i <= n; ++i)
        scanf("%d", &color[i]);
    dfs2(1);
    printf("%d
", t);
    return 0;
}
View Code

看到网上聚聚的解析,都不用建树搜索,直接判断某节点是否与其父节点目标颜色一致,若不一致一定需要额外一次染色,代码如下:

const int maxm = 1e4 + 10;

int color[maxm], now[maxm], father[maxm], n, t;


int main() {
    scanf("%d", &n);
    for (int i = 2; i <= n; ++i)
        scanf("%d", &father[i]);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &color[i]);
    for (int i = 1; i <= n; ++i)
        if(color[i] != color[father[i]])
            ++t;
    printf("%d
", t);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/GRedComeT/p/11238179.html