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;

}
发布了90 篇原创文章 · 获赞 18 · 访问量 3363

猜你喜欢

转载自blog.csdn.net/sherry_zhen/article/details/103261341
今日推荐