• 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;
    }
    
    

  • 相关阅读:
    UVA10090 数论基础 exgcd
    UVA 10037 贪心算法
    ST表入门学习poj3264 hdu5443 hdu5289 codeforces round #361 div2D
    poj3254状压DP入门
    I.点进来吧,这里有你想要的(01背包)
    J.哭泣的阿木木(线段树模板题)
    可怜的ljb(树状数组,逆序对)
    D武器大师的宝贝(最大相交区间,异或,最大公约数)
    银行排队模拟(队列,模拟,数据结构)
    B
  • 原文地址:https://www.cnblogs.com/Levi-0514/p/9092863.html
Copyright © 2020-2023  润新知