Pavel and barbecue - CF756A DFS 思维

Posted xuwanwei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pavel and barbecue - CF756A DFS 思维相关的知识,希望对你有一定的参考价值。

题目链接

CF756A

题目

Pavel cooks barbecue. There are n skewers, they lay on a brazier in a row, each on one of n positions. Pavel wants each skewer to be cooked some time in every of n positions in two directions: in the one it was directed originally and in the reversed direction.

Pavel has a plan: a permutation p and a sequence b 1,?b 2,?...,?b n, consisting of zeros and ones. Each second Pavel move skewer on position i to position p i, and if b i equals 1 then he reverses it. So he hope that every skewer will visit every position in both directions.

Unfortunately, not every pair of permutation p and sequence b suits Pavel. What is the minimum total number of elements in the given permutation p and the given sequence b he needs to change so that every skewer will visit each of 2n placements? Note that after changing the permutation should remain a permutation as well.

There is no problem for Pavel, if some skewer visits some of the placements several times before he ends to cook. In other words, a permutation p and a sequence b suit him if there is an integer k ( k?≥?2n), so that after k seconds each skewer visits each of the 2n placements.

It can be shown that some suitable pair of permutation p and sequence b exists for any n.

Input
The first line contain the integer (n (1?≤?n?≤?2·10^5)) — the number of skewers.

The second line contains a sequence of integers (p_1,?p_2,?...,?p_n (1?≤?p_i?≤?n)) — the permutation, according to which Pavel wants to move the skewers.

The third line contains a sequence (b_1,?b_2,?...,?b_n) consisting of zeros and ones, according to which Pavel wants to reverse the skewers.

Output
Print single integer — the minimum total number of elements in the given permutation p and the given sequence b he needs to change so that every skewer will visit each of 2n placements.

Examples
Input

4
4 3 2 1
0 1 1 1

Output

2

Input

3
2 3 1
0 0 0

Output

1

Note
In the first example Pavel can change the permutation to 4,?3,?1,?2.

In the second example Pavel can change any element of b to 1.

题意

有n个位置和n个肉串,需要把每个串串在每个地方两面都烤过才可以吃,现在有一个序列p,(p_i)表示在放在i的肉串下一个都被放到(p_i)。有序列b,当(b_i)为1时,这个位置要进行翻面。让你对p和b的元素进行最少的修改,让所有肉串都能吃。

思路

  • 理解一下第一个样例的NOTE的4,3,1,2:

    • 对于第一个位置的肉串:1->4->2->3->1->4->2->3->1...,于此同时翻面:0->1->0->1->1->0->1->0->0->...。 第二个:2->3->1->4->2->3->1->4->2...,...
    • 每个肉串都正反两面在所有地方烤了。
    • 观察看看,有环,而且两个环里面正反面不同。
  • 让每个肉串在每个地方烤过

    • 意思就是p可以成一个环,这样每个地方的肉串都可以绕一圈又一圈,去到每个地方。
    • 判断环可以用dfs
    • 对于原来给的p序列,不能成一个环的话,会成多个环,例如样例1的p会成两个环。我们的目标是一个环,所以要将多个环合成一个环。观察一下,就可以发现,x个环合成一个环最少要修改x条边。每个环修改一条。
    • 注意如果本身就1个环的话,就不需要修改了,否则有多少环修改多少次。
  • 让每个肉串在每个地方两面都烤过

    • 意思就是一个环绕两圈,这一圈的每个面要和上一圈的面不一样。
    • 要让第二圈的面和第一圈的面不同,那么第一次绕回原点的时候,原点的面应该和一开始的时候的面不一样了,要实现这个,就只要保证这一圈中翻面的次数是奇数就好了。
    • 如果翻面次数是偶数,那修改次数要+1,用来增加/减少一次翻面。

代码

#include<bits/stdc++.h>
using namespace std;
const int MAXN=200005;
int n;
int p[MAXN],b[MAXN];
bool vis[MAXN];
void dfs(int x){
	while(!vis[x]){
		vis[x]=true;
		x=p[x];
	}
}
int main(){
	scanf("%d",&n);
	int ans=0;
	for(int i=1;i<=n;i++) scanf("%d",&p[i]);
	int cnt=0;
	for(int i=1;i<=n;i++){
		scanf("%d",&b[i]);
		if(b[i]==1) cnt++;
	}
	if(cnt%2==0) ans++;
	cnt=0;
	for(int i=1;i<=n;i++){
		if(vis[i]) continue;
		dfs(i);
		cnt++;
	}
	if(cnt!=1) ans+=cnt;
	printf("%d
",ans);
	return 0;
}

以上是关于Pavel and barbecue - CF756A DFS 思维的主要内容,如果未能解决你的问题,请参考以下文章

cf-Global Round2-E. Pavel and Triangles

CF 986A Fair——多源bfs

cf1037D. Valid BFS?(BFS?)

CF1037D Valid BFS?

「CF1037D」Valid BFS?

[CF1037D] Valid BFS?