zoukankan      html  css  js  c++  java
  • 小猪存钱罐

    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

    sol:两种方法:1.强连通分量缩圈;2.并查集
    方法一中样例用有向图表示为:

    缩圈后有两个入度为0的点,所以答案为2.

    缩圈写法:

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define N 1000005
     4 int n,w,head[N],nxt[N],ans,size[N];
     5 int to[N],cnt,dfn[N],st[N],r,k[N];
     6 int low[N],tot,top,num[N];
     7 bool vis[N];
     8 using namespace std;
     9 inline void read(int &x){
    10     int datta=0;char chchc=getchar();bool okoko=0;
    11     while(chchc<'0'||chchc>'9'){if(chchc=='-')okoko=1;chchc=getchar();}
    12     while(chchc>='0'&&chchc<='9'){datta=datta*10+chchc-'0';chchc=getchar();}
    13     x=okoko?-datta:datta;
    14 }
    15 inline void link(int a,int b){to[++cnt]=b,nxt[cnt]=head[a],head[a]=cnt;}
    16 inline void t(int x){
    17     dfn[x]=low[x]=++tot;
    18     st[++top]=x;int ttt=top;
    19     for(int i=head[x];i;i=nxt[i]){
    20         int u=to[i];
    21         if(!num[u]){
    22             if(!dfn[u])t(u);
    23             low[x]=min(low[u],low[x]);
    24         }
    25     }
    26     if(dfn[x]==low[x]){
    27         r++;
    28         while(top>=ttt)
    29             num[st[top--]]=r,size[r]++;
    30     }
    31 }
    32 int main(){
    33     read(n);
    34     for(int i=1;i<=n;i++)
    35         read(w),link(w,i);
    36     for(int i=1;i<=n;i++)
    37         if(!dfn[i])t(i);
    38    for(int i=1;i<=n;i++)
    39         for(int j=head[i];j;j=nxt[j])
    40             if(num[to[j]]!=num[i])k[num[to[j]]]++;
    41     for(int i=1;i<=r;i++)
    42         if(!k[i])ans++;
    43     printf("%d
    ",ans); 
    44     return 0;
    45 }

    并查集写法:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int fa[1000001],n,ans;
     4 bool flag[1000001];
     5 int get(int x){
     6     if(fa[x]!=x)fa[x]=get(fa[x]);
     7     return fa[x];
     8 }
     9 int main() {
    10     scanf("%d",&n);
    11     for(int i=1;i<=n;i++){
    12         fa[i]=i;
    13     }
    14     for(int i=1;i<=n;i++)
    15     {
    16         int x;
    17         scanf("%d",&x); 
    18         //第x个box的KEY在第i个box里,将它们并成一个集合
    19         int p=get(x),q=get(i);
    20         if(p!=q)
    21         {
    22             fa[p]=q;
    23         }
    24     }
    25     for(int i=1;i<=n;i++)
    26     {
    27         int x=get(i);
    28         if(fa[i]==i) //统计有多少个集合,就有打开多少个box
    29         {
    30             ans++;
    31             flag[x]=true;
    32         }
    33     }
    34     printf("%d",ans);
    35     return 0;
    36 }
  • 相关阅读:
    IXmlSerializable With WCFData Transfer in Service Contracts
    Difference Between XmlSerialization and BinarySerialization
    Using XmlSerializer (using Attributes like XmlElement , XmlAttribute etc ) Data Transfer in Service Contracts
    Introducing XML Serialization
    Version Tolerant Serialization
    Which binding is bestWCF Bindings
    Data Transfer in Service Contracts
    DataContract KnownTypeData Transfer in Service Contracts
    Using the Message ClassData Transfer in Service Contracts
    DataContract POCO SupportData Transfer in Service Contracts
  • 原文地址:https://www.cnblogs.com/cutepota/p/12747761.html
Copyright © 2011-2022 走看看