B. pSort
题目链接:
http://codeforces.com/problemset/problem/28/B
题意:
给一个n,原本有个1到n按顺序排列的序列,给一个序列问,在给一个数组,表示这个位置的数可以换到pi位置,问能不能实现给的那个序列的排列。如果可以输出yes相反输出no
思路:
通过画图可知同一个集合的数字一定可以相互交换位置。所以这里使用并查集就好。
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define LL long long 3 4 using namespace std; 5 const int maxn=100+100; 6 struct node 7 { 8 int to,Next; 9 }; 10 int Head[maxn]; 11 node Edge[maxn*2]; 12 int cnt=0; 13 int a[maxn],b[maxn],Fa[maxn]; 14 void add(int u,int v) 15 { 16 Edge[++cnt].to=v; 17 Edge[cnt].Next=Head[u]; 18 Head[u]=cnt; 19 return ; 20 } 21 int Find(int x) 22 { 23 if(x==Fa[x]) 24 { 25 return x; 26 } 27 else 28 { 29 return Fa[x]=Find(Fa[x]); 30 } 31 } 32 int main() 33 { 34 int n; 35 cin>>n; 36 for(int i=1;i<=n;i++) 37 { 38 Fa[i]=i; 39 } 40 for(int i=1;i<=n;i++) 41 { 42 cin>>a[i]; 43 } 44 for(int i=1;i<=n;i++) 45 { 46 cin>>b[i]; 47 } 48 for(int i=1;i<=n;i++) 49 { 50 if(i+b[i]<=n||i-b[i]>=1) 51 { 52 int root1=Find(i); 53 if(i+b[i]<=n) 54 { 55 int root2=Find(i+b[i]); 56 if(root1!=root2) 57 { 58 Fa[root2]=root1; 59 } 60 } 61 if(i-b[i]>=1) 62 { 63 int root2=Find(i-b[i]); 64 if(root1!=root2) 65 { 66 Fa[root2]=root1; 67 } 68 } 69 } 70 } 71 int flag=1; 72 for(int i=1;i<=n;i++) 73 { 74 int root1=Find(a[i]); 75 int root2=Find(i); 76 if(root1!=root2) 77 { 78 //cout<<i<<" "<<a[i]<<endl; 79 flag=0; 80 break; 81 } 82 } 83 if(flag) 84 { 85 cout<<"YES"<<endl; 86 } 87 else 88 { 89 cout<<"NO"<<endl; 90 } 91 return 0; 92 }