zoukankan      html  css  js  c++  java
  • 百度之星初赛(A)——T2

    数据分割

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

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

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

    请帮助他恢复这些分隔符。

    Input

    11行:一个数字LL,表示后面输入的总行数。

    之后LL行,每行包含三个整数,i,j,ei,j,e,描述一个相等/不等的约束条件,若e=1e=1,则该约束条件为x_i = x_jxi​​=xj​​ ,若e=0e=0,则该约束条件为 x_i eq x_jxi​​xj​​ 。

    i,j,L leq 100000i,j,L100000

    x_i , x_j leq Lxi​​,xj​​L

    Output

    输出共T+1T+1行。

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

    接下来TT行的第ii行,一个整数,表示第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
    ———————————————————————————————————————
    因为相等具有传递性所以我们可以用并查集维护一波
    但是不等于不具有传递性所以我们可以用平衡树维护一波
    当然这里我用的是set
    这样之后呢 等于我们就可以把他们扔在一个并查集里面
    不等于的就把不等于他的扔进他的平衡树里面
    每次询问
    如果是一对相等的数
    我们就找一波他们是否在同一个并查集里 是就直接继续下一波
    不是就找他们是否存在对方的平衡树里面 当然这里我们强行把size小的合并进大的里面保证复杂度
    如果是不相等就判断他们是否同属一个并查集
    是就清空一波 记录答案
    不然就把他们加入对方的平衡树里面
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<set>
    using namespace std;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int T,f[200007];
    int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
    set<int>tr[200007];
    int vis[200007],cnt=1;
    int ans[200007],ap;
    int stk[200007],stp;
    int a,b,h;
    void clear(){
        while(stp){
            int x=stk[--stp];
            tr[x].clear();
            f[x]=x;
        }
        ++cnt;
    }
    int main()
    {
        T=read();
        for(int i=0;i<=200000;i++) f[i]=i;
        for(int i=1;i<=T;i++){
            a=read(); b=read(); h=read();
            if(vis[a]!=cnt) stk[stp++]=a,vis[a]=cnt;
            if(vis[b]!=cnt) stk[stp++]=b,vis[b]=cnt;
            int p=find(a),q=find(b);
            if(tr[p].size()<tr[q].size()) swap(p,q);
            if(h==1){
                if(p==q) continue;
                if(tr[p].find(q)!=tr[p].end()){
                    clear();
                    ans[++ap]=i;
                    continue;
                }
                f[q]=p;
                for(set<int>::iterator it=tr[q].begin();it!=tr[q].end();it++){
                    int z=*it;
                    tr[z].erase(q);
                    tr[z].insert(p);
                    tr[p].insert(z);
                }
                tr[q].clear();
            }
            else{
                if(p==q){
                    clear();
                    ans[++ap]=i;
                    continue;
                }
                tr[p].insert(q);
                tr[q].insert(p);
            }
        }
        printf("%d
    ",ap);
        for(int i=1;i<=ap;i++) printf("%d
    ",ans[i]-ans[i-1]);
        return 0;
    }
    View Code


  • 相关阅读:
    算法学习记录单链表
    算法学习记录排序
    算法学习记录图——最小生成树之prim算法
    算法学习记录图——应用之拓扑排序(Topological Sort)
    算法学习记录图(DFS BFS)
    算法学习记录排序——冒泡排序(Bubble Sort)
    算法学习记录图——最小路径之Floyd算法
    自用SqlHelper.cs
    WPF的DataGrid的标题加粗样式
    .NET Framework 4.0不能用sqlite的问题解决方法
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7351290.html
Copyright © 2011-2022 走看看