1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

問題

見た感じ

スワップできる数字の組が例えば(1,2)(2,3)だとしたら、このスワップを組み合わせて、p[1],p[2],p[3]を好きな順番にならべ変えることができて、おそらく要素数が増えたとしても同じように、好きな順番に挿入していけそう。
だから、重要なのはこの数字の組でどれだけの数字がグループになっているかで並び方は関係ない。
例えば{(1,3),(3,6)}がスワップできる数字の組だとすると
最初に与えられたpの{p[1],p[3],p[6]}に1が含まれていれば、スワップによって好きな順番に並べられるので、p[1]=1とすることができるし、もし含まれなければ絶対に無理。
だから、スワップできる数字のグループを持っていて、数字同士が同じグループにいるかが早く判定できればよいので、union-find treeを使って実装した。

解法

union-find tree 上でスワップ可能な数字の組をmergeしていって、最後に各iについて、iとp[i]が同じグループに入っているかどうかを調べ、入っていれば、ansを1増やしていった。

ソースコード

struct uftree{
    int n;
    int cou;
    vector<int> parent;
    vector<int> rank;
    vector<int> _size;
    uftree(int n):n(n){
        parent=vector<int>(n);
        rank=vector<int>(n,0);
        _size=vector<int>(n,1);
        cou=n;
        rep(i,n){
            parent[i]=i;
        }
    }
    int root(int i){
        return parent[i]==i?i:parent[i]=root(parent[i]);
    } 
    bool same(int i,int j){
        return root(i)==root(j);
    }
    void merge(int i,int j){
        i=root(i);j=root(j);
        if(i==j)return;
        cou--;
        if(rank[i]>=rank[j]){
            parent[j]=i;
            _size[i]+=_size[j];
        }else{
            parent[i]=j;
            _size[j]+=_size[i];
        }
        if(rank[i]==rank[j])rank[i]++;
        return;
    }
    int count(){
        return cou;
    }
    int unitsize(int i){
        return _size[root(i)];
    }
};
const int N_MAX=100005;
int n,m,p[N_MAX];

int main(){
    int x,y;
    //入力
    cin>>n>>m;
    rep(i,n)cin>>p[i];
    uftree tree(n);
    rep(i,m){
        cin>>x>>y;
        tree.merge(x-1,y-1);
    }
    //処理
    int ans=0;
    rep(i,n){
        if(tree.same(p[i]-1,i))ans++;
    }
    //出力
    cout << ans <<endl;
}

振り返り

unionfind tree が生き生きしてるのは初めてだった

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?