Pavel and barbecue - CF756A DFS 思维
Posted xuwanwei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pavel and barbecue - CF756A DFS 思维相关的知识,希望对你有一定的参考价值。
题目链接
题目
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 思维的主要内容,如果未能解决你的问题,请参考以下文章