Codeforces 760C Pavel and barbecue【思维+Dfs】
2017-01-23 16:22
344 查看
C. Pavel and barbecue
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
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
b1, b2, ..., bn, consisting of zeros and ones. Each second Pavel move skewer on position
i to position pi, and if
bi 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·105) — the number of skewers.
The second line contains a sequence of integers p1, p2, ..., pn (1 ≤ pi ≤ n) —
the permutation, according to which Pavel wants to move the skewers.
The third line contains a sequence b1, b2, ..., bn 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
Output
Input
Output
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个串串,一开始正面朝上放在N个位子上。一秒之后,在位子i的串串会移动到pi位子上,并且如果bi==1,那么我们还要将串串翻个面。
现在要求每个串串都要在每个位子的反正面都被烤过才能吃,然而现在的机制不一定能够完成任务,让你修改最少的操作,使得满足这个操作。
思路:
1、翻译过来就是,我们现在在任意一个位子都要能够到其他所有位子并且还能回归到原位子,而且回归到原位子的时候一定要翻个面了才行。
现在一个串串能够到其他所有位子并且最后回到原位子,那么其一定翻面的次数为:Σb【i】;那么回归到原位子的时候的朝向就是:Σb【i】%2.只有其为1的时候,才能够保证回来的时候翻面了。
那么很肯定,Σb【i】如果是偶数,那么我们将任意一个b【i】是0的变成1即可(或者从1变成0都行)。
2、那么对应一个位子能够到其他所有位子并且回到原位子,那么操作最终会形成一个环。
如果原来就能操作出来一个环,那么对应就不需要进行什么操作了,反之,如果原来的操作不能成一个环,那么我们统计一共有多少个环。O(n)Dfs即可。
然后将每一个环都扯出来一条边与其他环相连,那么需要的最小改动也就是环的个数。
将这两个部分都处理好,那么问题就解决了。
Ac代码:
#include<stdio.h>
#include<string.h>
using namespace std;
int a[200060];
int vis[200060];
int b[200060];
void Dfs(int u)
{
vis[u]=1;
if(vis[a[u]]==0)
{
Dfs(a[u]);
}
}
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(vis,0,sizeof(vis));
int output=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
int cnt=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
if(b[i]==1)cnt++;
}
if(cnt%2==0)output++;
cnt=0;
for(int i=1;i<=n;i++)
{
if(vis[i]==0)
{
cnt++;
Dfs(i);
}
}
if(cnt==1)cnt=0;
printf("%d\n",output+cnt);
}
}
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
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
b1, b2, ..., bn, consisting of zeros and ones. Each second Pavel move skewer on position
i to position pi, and if
bi 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·105) — the number of skewers.
The second line contains a sequence of integers p1, p2, ..., pn (1 ≤ pi ≤ n) —
the permutation, according to which Pavel wants to move the skewers.
The third line contains a sequence b1, b2, ..., bn 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个串串,一开始正面朝上放在N个位子上。一秒之后,在位子i的串串会移动到pi位子上,并且如果bi==1,那么我们还要将串串翻个面。
现在要求每个串串都要在每个位子的反正面都被烤过才能吃,然而现在的机制不一定能够完成任务,让你修改最少的操作,使得满足这个操作。
思路:
1、翻译过来就是,我们现在在任意一个位子都要能够到其他所有位子并且还能回归到原位子,而且回归到原位子的时候一定要翻个面了才行。
现在一个串串能够到其他所有位子并且最后回到原位子,那么其一定翻面的次数为:Σb【i】;那么回归到原位子的时候的朝向就是:Σb【i】%2.只有其为1的时候,才能够保证回来的时候翻面了。
那么很肯定,Σb【i】如果是偶数,那么我们将任意一个b【i】是0的变成1即可(或者从1变成0都行)。
2、那么对应一个位子能够到其他所有位子并且回到原位子,那么操作最终会形成一个环。
如果原来就能操作出来一个环,那么对应就不需要进行什么操作了,反之,如果原来的操作不能成一个环,那么我们统计一共有多少个环。O(n)Dfs即可。
然后将每一个环都扯出来一条边与其他环相连,那么需要的最小改动也就是环的个数。
将这两个部分都处理好,那么问题就解决了。
Ac代码:
#include<stdio.h>
#include<string.h>
using namespace std;
int a[200060];
int vis[200060];
int b[200060];
void Dfs(int u)
{
vis[u]=1;
if(vis[a[u]]==0)
{
Dfs(a[u]);
}
}
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(vis,0,sizeof(vis));
int output=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
int cnt=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
if(b[i]==1)cnt++;
}
if(cnt%2==0)output++;
cnt=0;
for(int i=1;i<=n;i++)
{
if(vis[i]==0)
{
cnt++;
Dfs(i);
}
}
if(cnt==1)cnt=0;
printf("%d\n",output+cnt);
}
}
相关文章推荐
- 【codeforces 760C】Pavel and barbecue
- CodeForces 760C Pavel and barbecue
- CodeForces 760C Pavel and barbecue【英文题】
- codeforces-Fox And Two Dots【DFS】(思维)
- Codeforces 682C Alyona and the Tree【Dfs+YY思维】好题
- Codeforces Round #393 (Div. 2) C Pavel and barbecue(思维)
- 【CodeForces 525D】【dfs+思维】 Arthur and Walls 【只包含点和星的矩阵,需要将部分星变成点使点能组成矩形 】
- codeforces 877 problem E Danil and a Part-time Job 【dfs序 + 线段树区间异或修改】
- Codeforces 638C Road Improvement【思维+Dfs】
- Codeforces--525D--Arthur and Walls(DFS)
- CodeForces - 296D.Greg and Graph(Floyd+逆序思维)
- codeforces 370div.2 C Memory and De-Evolution[逆向思维]【思维】
- CodeForces 354A - Vasya and Robot (简单思维)
- CodeForces 780C Andryusha and Colored Balloons (DFS)
- CodeForces 547D Mike and Fish 思维
- codeforces 764C Timofey and a tree (思维题)
- Codeforces 526C - Om Nom and Candies (贪心 + 思维)
- CodeForces - 842C Ilya And The Tree 树上DFS
- Codeforces 456 div2 A B ***D(思维题) ***E(二分/DFS/数论)
- CodeForces_507B_Amr and Pins(思维题)