zoukankan      html  css  js  c++  java
  • SPOJ:Lost and survived(multiset+并查集)

    On September 22, 2004, Oceanic Flight 815 crashed on a mysterious island somewhere in the pacific.

    There actually were survivors in the crash , N survivors . The mysterious island kept on moving in space - time, so no rescue reached them.

    Initially every survivor was on his own .But soon they realized there are these “The Others” (Scientists of damn Dharma Initiative) on this Island too.

    So to protect themselves from mad Scientists they started uniting into groups after Dr. Shephard  said  “ Live together Die alone ”.

    You have to handle Q queries; which consist of two survivors becoming friends and thereby uniting there respective groups into a  larger group.

    After each query, output the difference between the group of largest size and group of smallest size at that time.

    If there is only one group, output 0. At first, everyone is in their own group.

    Also note, if the two survivors in the query are already in the  same group, print the current answer, and skip merging groups.

    Also do comment if you have watched Lost :-p

    Input

    The first line consists of two space separated integers, N and Q
    The next Q line consists of two integers, A and B, meaning that 
    the groups involving survivor A and survivor B unite into a larger group.

    The first line consists of two space separated integers, N and Q

    The next Q line consists of two integers, A and B, meaning that 

    survivor A and survivor B became friends uniting there groups.

    Output

    Output Q lines, the answer after each query.

    1<=N<=100000

    1<=Q<=100000

    Example

    Input:
    5 3
    1 2
    2 3
    5 4
    
    Output:
    1
    2
    1

     题意:有N个人,一开始都自己一个集合。有Q次操作,每次给定u,v,要求合并u和v到一个集合(已经在就忽略),然后输出目前的最大集合元素个数减去最小集合元素个数。

    思路:集合用并查集表示,元素个数用multiset保存。

    注意multiset的删除:s.erase(find(x)),只删除一个;而 s.erase(x), 会删除所有值为x的元素    

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=100010;
    multiset<int>s;
    int fa[maxn],num[maxn],Max=1,Min=1;
    int find(int u){
        if(u==fa[u]) return u;
        fa[u]=find(fa[u]); return fa[u];
    }
    void merge(int u,int v){
        int fau=find(u),fav=find(v);
        if(num[fau]>num[fav]) swap(fau,fav);
        fa[fau]=fav;
        s.erase(s.find(num[fau])); s.erase(s.find(num[fav]));
        num[fav]+=num[fau];    s.insert(num[fav]);  
        if(num[fav]>Max) Max=num[fav];
        Min=*s.begin();
    }
    int main()
    {
        int N,Q,u,v,i,j,ans;
        scanf("%d%d",&N,&Q);
        for(i=1;i<=N;i++){
            fa[i]=i; num[i]=1;
            s.insert(1);
        }
        while(Q--){
            scanf("%d%d",&u,&v);
            if(find(u)!=find(v))  merge(u,v);
            printf("%d
    ",Max-Min);
        }
        return 0;
    }
     
  • 相关阅读:
    软件项目不同角色的职责
    Flex与.NET互操作(四):使用HttpService、URLReqeust和URLLoader加载/传输数据
    Flex与.NET互操作(一):基于Socket的网络连接
    ActionScript 3.0 Step By Step系列(一):工欲其善,先利其器(Flex Builder)
    Flex与.NET互操作(三):基于WebService的数据访问(下)
    编写jQueryUI插件(widget)(转载)
    编写一个简单的widget
    wcf系列学习5天速成——第五天 服务托管(转载)
    解决WCF双工通讯模式中向ChannelFactory提供的InstanceContext包含未实现CallbackContractType的问题
    .NET简谈事务本质论(转载)
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8973933.html
Copyright © 2011-2022 走看看