zoukankan      html  css  js  c++  java
  • [Poi2005]Piggy Banks小猪存钱罐

    Description

    Byteazar有 N 个小猪存钱罐. 每个存钱罐只能用钥匙打开或者砸开. Byteazar已经把每个存钱罐的钥匙放到了某
    些存钱罐里. Byteazar 现在想买一台汽车于是要把所有的钱都取出来. 他想尽量少的打破存钱罐取出所有的钱,问
    最少要打破多少个存钱罐.

    Input

    第一行一个整数 N (1 <= N <= 1.000.000)表示存钱罐的总数. 
    接下来每行一个整数,第 i+1行的整数代表第i个存钱罐的钥匙放置的存钱罐编号.

    Output

    一个整数表示最少打破多少个存钱罐.

    Sample Input

    4
    2
    1
    2
    4
    

    Sample Output

    2
    这道题是可以用并查集来做
    难度不大
    见代码
    #include<bits/stdc++.h>
    using namespace std;
    int ans,a[1000001];
    int find(int x){return a[x]==x?x:a[x]=find(a[x]);}//并查集路径压缩
    int main()
    {
        int n;
        cin>>n;
        for (int i=1;i<=n;i++) 
    a[i]=i; for (int i=1;i<=n;i++) { int x; cin>>x; if (x!=i) a[find(i)]=find(x);//合并两个集合 } for (int i=1;i<=n;i++) if (a[i]==i)
    ans++;//有几个独立的集合 cout<<ans<<endl; return 0; }

    ending。。。。。。

     
    #include<iostream>
    using namespace std;
    int ans,pre[1000001];
    int find(int x){return pre[x]==x?x:pre[x]=find(pre[x]);}
    //并查集的“查”+路径压缩
    int main()
    {
        int n;
        cin>>n;
        for (int i=1;i<=n;i++) pre[i]=i;
        for (int i=1;i<=n;i++)
        {
            int x;
            cin>>x;
            if (x!=i)//貌似这句话不写也可以,但还是写着吧
            pre[find(i)]=find(x);//合并两个集合
        }
        for (int i=1;i<=n;i++)
        if (pre[i]==i) ans++;//有几个独立的集合
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    【费用流】【CODEVS】1227 方格取数2
    【CODEVS】1034 家园
    【BZOJ】1066: [SCOI2007]蜥蜴
    【最大流】【CODEVS】1993 草地排水
    【HDU】2191 多重背包问题
    【TYVJ】1520 树的直径
    【BZOJ】1984 月下“毛景树”
    【BZOJ】1588: [HNOI2002]营业额统计
    【NOI】2004 郁闷的出纳员
    【POJ】2892 Tunnel Warfare
  • 原文地址:https://www.cnblogs.com/kevin6666/p/10951578.html
Copyright © 2011-2022 走看看