zoukankan      html  css  js  c++  java
  • Parity game POJ

    题意:现在有一个长度为n的零一串,给出m次查询,每次查询格式为:从第u位到第v位的1的个数为奇数或者偶数,其中
    “even” 是偶数的意思“odd” 是奇数的意思。问,前几个查询是正确的,也就是第一个错误的查询的前一条查询是第几次查询。


        思路:带权并查集,权值为  本节点到父亲节点的1的个数的奇偶性,偶数为0,奇数为1,由于n很大,我们开不了这么大的数组,但是m只有5000,所以我们考虑压缩一下。  看代码操作

    #include<iostream>
    #include<map>
    #include<cstring>
    using namespace std;
    const int Max=10005;
    struct node//记录父亲节点和权值
    {
        int par,relation;
    };
    node p[Max];
    map<int ,int > mmp;//数据比较大,所以用map压缩
    int n,m,cnt,ans,flag;
    void init()
    {
        flag=cnt=0;
        mmp.clear();
        for(int i=1;i<Max;i++){
            p[i].par=i;
            p[i].relation=0;
        }
    }
    int Hash(int x)//hash,压缩函数
    {
        if(mmp.find(x)==mmp.end())//对应数字出现的顺序,由于查询只有5000次,所最多会出现10000个数字
        mmp[x]=cnt++;             //这样就将1e9的数据压缩到了1e5的范围里面
        return mmp[x];
    }
    int Find(int x)//查找函数
    {
        if(x==p[x].par)
            return x;
        int tmp=p[x].par;
        p[x].par=Find(tmp);
        p[x].relation^=p[tmp].relation;//权值的转移
        return p[x].par;
    }
    bool unite(int x,int y,int c)
    {
        int root1=Find(x);
        int root2=Find(y);
        if(root1!=root2){//根不同,将y的根连到x的根上面
            p[root2].par=root1;
            p[root2].relation=c^p[x].relation^p[y].relation;//权值的转移
        }
        else{//根相同则直接判断是否正确
            if(c!=p[x].relation^p[y].relation)
                return 0;
        }
        return 1;
    }
    int main()
    {
        int u,v,tmp;
        char str[10];
        while(cin>>n>>m){
            init();
            for(int i=0;i<m;i++){
                cin>>u>>v>>str;
                if(u>v) swap(u,v);;
                u=Hash(u-1);
                v=Hash(v);
                if(str[0]=='e') tmp=0;
                else tmp=1;
                if(!flag&&!unite(u,v,tmp)){
                        ans=i;
                        flag=1;
                }
            }
            if(!flag)//需要注意的是,如果所有的查询都正确,那么直接输出查询的次数即可
                cout<<m<<endl;
            else
                cout<<ans<<endl;
        }
        return 0;
    }
    
    

  • 相关阅读:
    Clipper库中文文档详解
    JavaScript-Clipper.js
    安装Scrapy遇到的问题
    Python中if __name__ == '__main__'的使用
    写出一段Python代码实现删除一个list里面的重复元素
    Python 内置函数(反射类)
    Python 内置函数(集合操作,IO操作)
    Python 内置函数(数学运算类,逻辑判断类)
    Python 推导式(列表推导式,字典推导式,集合推导式)
    Python 闭包和装饰器
  • 原文地址:https://www.cnblogs.com/Levi-0514/p/9092863.html
Copyright © 2011-2022 走看看