题解 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;
}

原文地址:https://www.cnblogs.com/ahawzlc/p/12857265.html