题解 CF28B 【pSort】
思路:并查集
首先我们知道,假如 a 可以变换成 b,b 可以变换成 c,那么 a 可以变换成 c ,这个也是并查集find()
操作的主打功能。
题目要求其实就是把数列[1,n]
变换成题目所给序列,并且给了每个位置能变换到哪个位置。
那么我们把每个位置和这个位置能够变换到的位置merge()
起来,最后查看目标位置和原位置是否在一个并查集中,即可得到答案。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=105;
int f[N],to[N],d[N];
int find(int x) {
if(f[x]!=x) f[x]=find(f[x]);
return f[x];
}
void merge(int x,int y) {
x=find(x);
y=find(y);
if(x!=y) f[x]=y;
}
int main() {
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) {
f[i]=i;
scanf("%d",&to[i]);
}
for(int i=1;i<=n;i++) {
scanf("%d",&d[i]);
if(i-d[i]>0) merge(i,i-d[i]);
if(i+d[i]<=n) merge(i,i+d[i]);//注意不要越界
}
for(int i=1;i<=n;i++) {
if(find(i)==find(to[i])) continue;
puts("NO");
return 0;
}
puts("YES");
return 0;
}
任何一个伟大的计划,都有一个微不足道的开始