B - Swap to Sort(并查集)

题目:
You are given an array A[1…N]A[1…N] with integers in decreasing order and a list of pairs (a1,b1)(a1,b1), (a2,b2),(a2,b2), ……, (aK,bK)(aK,bK). You wish to sort the array AA in increasing order, each turn you choose an ii (ii can be chosen multiple times) and swap A[ai]A[ai] with A[bi]A[bi]. Determine whether this is possible.

Input

The first line contains two integers, representing NN and KK respectively (1≤N,K≤1061≤N,K≤106). The following KK lines each contains two integers, representing aiai and bibi respectively (1≤ai<bi≤N1≤ai<bi≤N).

Output

Output “Yes” if it is possible to sort the array in increasing order, “No” otherwise.

Sample Input 1 Sample Output 1
5 2
1 5
2 4
Yes

Sample Input 2 Sample Output 2
5 4
1 4
2 3
4 5
1 5
题意:给出N,K:从1-N个数为从小到大的顺序;
k行:ai,bi表示有K次swap(ai,bi)可选择;
最多选择k次,问最后能否改变成N-1的顺序;
能输出Yes,不能输出No;

思路:当时比赛已经想到了大体思路,并查集也想到了,忘了模板,也不会去推导,并查集究其原因还是未理解本质。
并查集的思想:swap(ai,bi):使他们ai,bi合并Merge(ai,bi);
从1-N(或者1-N/2)跑一遍:若对于每一个i,Find(f[i])==Find(f[n+1-i])都成立表示Yes,否则No;

AC代码

#include <bits/stdc++.h>

using namespace std;
int f[1000010];//f[i]代表i属于的集合
int Find(int x)//寻找x最终属于的集合
{
    if(x==f[x])
        return x;
    else//容易出错
    {
        f[x]=Find(f[x]);//递归到最终的集合
        return f[x];
    }
}
void Merge(int a,int b)
{
    int t1=Find(a);
    int t2=Find(b);
    if(t1!=t2)
        f[t1]=t2;//容易出错
}
int main()
{
    ios::sync_with_stdio(0);
    int n,k;
    cin>>n>>k;
    for(int i=1; i <=n; i++)
        f[i]=i;//初始化i属于i
    while(k--)
    {
        int a,b;
        cin>>a>>b;
        Merge(a,b);
    }
    int flag=1;
    for(int i=1; i<=n; i++)
    {
        if(Find(f[i])!=Find(f[n+1-i]))//容易出错为f[i]==f[n+1-i]
        {
            flag=0;
            break;
        }
    }
    if(flag==1)
        cout<<"Yes"<<endl;
    else
        cout<<"No"<<endl;
    return 0;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值