zoukankan      html  css  js  c++  java
  • HDU 6109 数据分割(并查集+set)

    数据分割

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 2457    Accepted Submission(s): 748

    Problem Description
    小w来到百度之星的赛场上,准备开始实现一个程序自动分析系统。

    这个程序接受一些形如xi=xjxixj 的相等/不等约束条件作为输入,判定是否可以通过给每个 w 赋适当的值,来满足这些条件。

    输入包含多组数据。
    然而粗心的小w不幸地把每组数据之间的分隔符删掉了。
    他只知道每组数据都是不可满足的,且若把每组数据的最后一个约束条件去掉,则该组数据是可满足的。

    请帮助他恢复这些分隔符。
     
    Input
    1行:一个数字L,表示后面输入的总行数。

    之后L行,每行包含三个整数,i,j,e,描述一个相等/不等的约束条件,若e=1,则该约束条件为xi=xj ,若e=0,则该约束条件为 xixj

    i,j,L100000
    xi,xj
    Output
    输出共T+1行。

    第一行一个整数T,表示数据组数。

    接下来T行的第i行,一个整数,表示第i组数据中的约束条件个数。
     
    Sample Input
    6 2 2 1 2 2 1 1 1 1 3 1 1 1 3 1 1 3 0
     
    Sample Output
    1 6
     

    分析

    本题一开始以为要用种类并查集做,但是本题和种类并查集不同的是,种类并查集应用的情况是固定的种类数,也就是非此即彼的情况,但是本题来说 1和2不同 2和3不同 未必代表1和3就相同

    所以需要对于每一个根维护一个set 存储与其对立的根(注意是在根节点维护关于根的set,否则可能会出现遗漏)

    对于a和b已经在同一个集的情况 ,如果约束条件为0 则代表到了本组最后一个条件,进行初始化

    对于a和b不在同一个集的情况,如果约束条件为0 将彼此的根节点加入set中,如果约束条件为1 则遍历彼此根节点的set,如果不冲突就可以合并,注意合并的时候要把set一起合并,冲突的话说明到了本组最后一个条件,进行初始化

    #include<bits/stdc++.h>
    using namespace std;
    
    int s[100005],anss[100005],num,sum,cnt,l,L,c,now,a[100005],b[100005];
    
    set<int> st[100005];
    
    int findf(int x)
    {
        return x==s[x]?x:s[x]=findf(s[x]);
    }
    
    void hebing(int fa,int fb)
    {
        s[fa]=fb;
        set<int>::iterator it;
        for(it=st[fa].begin();it!=st[fa].end();it++)   //“敌人”也要一起合并 
        {
            st[fb].insert(*it);
        }
        for(it=st[fb].begin();it!=st[fb].end();it++)
        {
            st[fa].insert(*it);
        }
     } 
     
    int pd(int fa,int fb)
    {
        if(st[fa].count(fb)||st[fb].count(fa))   //set中有冲突的根 
        {
            return 0;
        }
        else
        {
            return 1;
        }
     } 
    
    void Init()
    {
        for(int i=0;i<now;i++)
        {
            s[a[i]]=a[i];   //初始化根节点
            st[a[i]].clear(); //清空“敌人”
            s[b[i]]=b[i];   
            st[b[i]].clear();
        }
        now=0;
        anss[cnt++]=num;
        num=0;
    }
    
    int main()
    {
        cin>>l;
        L=l;
        sum=0;
        cnt=0;
        now=0;
        for(int i=1;i<=L;i++)
        {
            s[i]=i;
        }
        while(l--)
        {
            cin>>a[now]>>b[now]>>c;
            num++;
            int fa=findf(a[now]);
            int fb=findf(b[now]);
            now++;
            if(fa==fb)       //已经在同一个类 
            {
                if(c==0)    //约束条件为不等
                {
                    sum++;
                    Init();
                } 
            }
            else   //现在还不在同一个类 
            {
                if(c==1)    //约束条件为相等 进行判断 
                {    
                    if(pd(fa,fb)==1)   //不冲突 可以合并
                    {
                        hebing(fa,fb);
                    } 
                    else
                    {
                        sum++;
                        Init();
                    } 
                }
                else       //约束条件为不等,加入set 
                {
                    st[fa].insert(fb);   //均以根为标记 
                    st[fb].insert(fa);
                }
            } 
        }
        cout<<sum<<endl;
        for(int i=0;i<cnt;i++)
        {
            cout<<anss[i]<<endl;
        } 
    }
  • 相关阅读:
    十二、 Spring Boot 静态资源处理
    九、 Spring Boot 拦截器
    docker之搭建私有仓库
    docker之Dokcerfile 常用指令
    docker之网络管理
    docker之故障问题解决方案
    docker之搭建LNMP
    docker之容器数据持久化
    都说岁月不饶人,我们又何曾饶过岁月
    docker之容器管理
  • 原文地址:https://www.cnblogs.com/dyhaohaoxuexi/p/12564905.html
Copyright © 2011-2022 走看看