专题测试四 图论 A - pSort
- 题目
One day n cells of some array decided to play the following game. Initially each cell contains a number which is equal to it's ordinal number (starting from 1). Also each cell determined it's favourite number. On it's move i-th cell can exchange it's value with the value of some other j-th cell, if |i - j| = di, where di is a favourite number of i-th cell. Cells make moves in any order, the number of moves is unlimited.
The favourite number of each cell will be given to you. You will also be given a permutation of numbers from 1 to n. You are to determine whether the game could move to this state.
InputThe first line contains positive integer n (1 ≤ n ≤ 100) — the number of cells in the array. The second line contains n distinct integers from 1 to n — permutation. The last line contains n integers from 1 to n — favourite numbers of the cells.
OutputIf the given state is reachable in the described game, output YES, otherwise NO.
Sample 1Input Output 5 5 4 3 2 1 1 1 1 1 1
YES
Input Output 7 4 3 5 1 2 7 6 4 6 6 1 6 6 1
NO
Input Output 7 4 2 5 1 3 7 6 4 6 6 1 6 6 1
YES
- 思路
写之前先吐槽下,这个星期的题都是些什么高达
元素可以换到自己最喜欢的距离上,意味着这个元素可以与自己距离d的元素任意交换
对于任意两个元素a和b,如果a能和c交换,b也能和c交换,那么经由c进行中转,a、b也能交换,而且可以不改变c处元素的值
所以任意两个可以交换的元素可以视为在一个连通块中,在一个连通块中的元素可以任意交换而不产生其他影响
用并查集判断每个元素当前位置和目标位置在不在一个连通块中,都满足则YES,不满足则NO - 代码
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> int fa[105],p[105],love[105]; int find(int x) { if(fa[x]!=x) fa[x] = find(fa[x]); return fa[x]; } void build(int x,int y) { int a=find(x); int b=find(y); fa[a] = b; } int main() { int n,q; long long ans; scanf("%d",&n); for(int i=1;i<=n;i++) fa[i] = i; for(int i=1;i<=n;i++) { scanf("%d",&q); p[q]=i; } for(int i=1;i<=n;i++) { scanf("%d",&love[i]); } for(int i=1;i<=n;i++) { if(i-love[i]>=1) build(i,i-love[i]); if(i+love[i]<=n) build(i,i+love[i]); } int f=1; for(int i=1;i<=n;i++) { if(find(p[i])!=find(i)) { f=0; break; } } if(f==1) { printf("YES\n"); } else { printf("NO\n"); } return 0; }