zoukankan      html  css  js  c++  java
  • HDU 6109 数据分割 并查集,SET

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6109

    题意:中文题面

    解法:每次都贪心地尝试将尽量多的条件放进当前这组,遇到第一个与已有条件冲突时,就是分割的时候。相等具有传递性,直接用并查集维护,不相等的关系用set维护,注意到x1=x2,x1!=x3,x2!=x4,那么有x1!=x4,x2!=x3,所以用并查集合并(x1,x2)的时候,就需要把x1的不等信息合并到x2上。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5+10;
    namespace DSU{
        int fa[maxn];
        int find_set(int x){
            if(x==fa[x]) return x;
            else return fa[x]=find_set(fa[x]);
        }
    };
    using namespace DSU;
    int n;
    set <int> S[maxn];
    void init(){
        for(int i=1; i<=n; i++){
            S[i].clear();
            fa[i]=i;
        }
    }
    int a[maxn], b[maxn], c[maxn];
    int ans[maxn];
    int main()
    {
        while(~scanf("%d", &n))
        {
            init();
            for(int i=1; i<=n; i++){
                scanf("%d %d %d", &a[i],&b[i],&c[i]);
            }
            int cnt = 0;
            for(int i=1; i<=n; i++){
                int u = find_set(a[i]);
                int v = find_set(b[i]);
                if(c[i] == 1){
                    if(u==v) continue;
                    else if(S[u].find(v)!=S[u].end()){
                        ans[++cnt] = i;
                        init();
                    }else{
                        for(set<int>::iterator it=S[v].begin(); it!=S[v].end(); it++){
                            S[u].insert(*it);
                            S[*it].erase(v);
                            S[*it].insert(u);
                        }
                        S[v].clear();
                        fa[v] = u;
                    }
                }
                else{
                    if(u==v){
                        ans[++cnt]=i;
                        init();
                    }else{
                        S[u].insert(v);
                        S[v].insert(u);
                    }
                }
            }
            printf("%d
    ", cnt);
            for(int i=1; i<=cnt; i++){
                printf("%d
    ", ans[i]-ans[i-1]);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    WMI介绍
    进程间通信
    回调函数(C/C++)
    漏洞名词介绍
    MD5 详解
    jQuery插件的写法
    node爬虫
    nodejs应用:文件上传
    node开发备注
    node生成自定义命令(yargs/commander)
  • 原文地址:https://www.cnblogs.com/spfa/p/7380170.html
Copyright © 2011-2022 走看看