zoukankan      html  css  js  c++  java
  • CDOJ1464 Parity Game [并查集]

    这道题我用的并查集做的。
    首先对数据做离散化。

    按给出的顺序依次处理每次问答。
    并查集每个节点维护三个值:
    root:该点的根节点(从根节点到该节点的整个区间的奇偶性已经确定);
    sign:该节点是否是某个奇偶性确定区间的右端点;
    eo:该集合的根节点到该点的区间的奇偶性;

    结束:在遇到某区间的奇偶性出现矛盾时结束(后来得到的奇偶性和之前确定的奇偶性不同)。

    每次先找到a-1和b的根节点;
    如果a-1没有根节点:

      如果b没有根节点:b的root设为a,更新b的sign,eo;
      如果b的根节点就是a,考察a到b区间是否出现矛盾;
      否则得到两个区间[fb,a-1]和[a,b],或[a,fb-1]和[fb,b],这两个区间的奇偶性都可得到,
      更新其奇偶性。

    如果a-1的根节点为fa:

      如果b没有根节点,b的根基点设为a,更新b的sign和eo;
      如果fa==fb,做奇偶性判断;
      否则,会从区间的并分解得到两个或三个互不相交的区间,这些区间的奇偶性可以得到。

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<string>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    #define PN printf("\n");
    
    char chrn;
    #define SCRN while(scanf("%c",&chrn) && chrn!='\n');
    
    typedef struct
    {
        int a,b,id,eo;
    }node1;
    
    typedef struct
    {
        int n,id,type;
    }node2;
    
    typedef struct
    {
        int root,sign,eo;
    }node3;
    
    int n,last;
    node1 a[5001];
    node2 b[10001];
    node3 set[10001];
    
    bool cmp(node2 a,node2 b)
    {
        if(a.n<b.n)
            return true;
        return false;
    }
    
    void discrete(int t)
    {
        int i,num,m;
        sort(b,b+t,cmp);
        num=0;
        m=b[0].n;
        for(i=0; i<t; i++)
        {
            if(b[i].n>m)
            {
                m=b[i].n;
                num++;
            }
            if(b[i].type==1)
                a[b[i].id].a=num;
            else
                a[b[i].id].b=num;
        }
    }
    
    void ini_set()
    {
        int i;
        for(i=0; i<=10000; i++)
            set[i].sign = 0;
    }
    
    int findroot(int k)
    {
        int root;
        if(k<0 || set[k].sign == 0)
            return -1;
        root = findroot(set[k].root-1);
        if(root == -1)
            return set[k].root;
        else
        {
            set[k].eo ^= set[set[k].root-1].eo;
            return set[k].root = root;
        }
    }
    
    void D()
    {
        int i,fa,fb,eo;
        node1 nd;
        last=0;
        ini_set();
        for(i=0; i<n; i++)
        {
            last++;
            nd = a[i];
            fa = findroot(nd.a-1);
            fb = findroot(nd.b);
            if(fa == -1)
            {
                if(fb == -1)
                {
                    set[nd.b].sign = 1;
                    set[nd.b].root = nd.a;
                    set[nd.b].eo = nd.eo;
                }
                else if(fb == nd.a)
                {
                    if(set[nd.b].eo != nd.eo){
                        //printf("OP2:");
                        return;
                    }
                }
                else if(fb < nd.a)
                {
                    set[nd.a-1].sign = 1;
                    set[nd.a-1].root = fb;
                    set[nd.a-1].eo = set[nd.b].eo ^ nd.eo;
                }
                else if(fb > nd.a)
                {
                    set[fb-1].sign = 1;
                    set[fb-1].root = nd.a;
                    set[fb-1].eo = set[nd.b].eo ^ nd.eo;
                    set[nd.b].root = nd.a;
                    set[nd.b].eo = nd.eo;
                }
            }
            else
            {
                if(fb == -1)
                {
                    set[nd.b].sign = 1;
                    set[nd.b].root = fa;
                    set[nd.b].eo = set[nd.a-1].eo ^ nd.eo;
                }
                else if(fa == fb)
                {
                    if((set[nd.b].eo ^ set[nd.a-1].eo) !=nd.eo)
                    {
                        //printf("OP1:");
                        return;
                    }
                }
                else if(fb<fa)
                {
                    set[fa-1].sign = 1;
                    set[fa-1].root = fb;
                    set[fa-1].eo = set[nd.a-1].eo ^ set[nd.b].eo ^ nd.eo;
                }
                else if(fb>fa && fb<nd.a)
                {
                    set[fb-1].sign = 1;
                    set[fb-1].root = fa;
                    set[fb-1].eo = set[nd.a-1].eo ^ set[nd.b].eo ^ nd.eo;
                }
                else if(fb>nd.a)
                {
                    set[fb-1].sign = 1;
                    set[fb-1].root = nd.a;
                    set[fb-1].eo = set[nd.b].eo ^ nd.eo;
                    findroot(nd.b);
                }
            }
        }
        last++;
    }
    
    int main()
    {
        int m,i,j;
        char s[5];
        while(scanf("%d",&m)!=EOF)
        {
            scanf("%d",&n);
            for(i=0,j=0; i<n; i++)
            {
                scanf("%d %d %s",&a[i].a,&a[i].b,s);
                if(s[0]=='e')
                    a[i].eo=0;
                else
                    a[i].eo=1;
                a[i].id=i+1;
                b[j].n=a[i].a;
                b[j].type=1;
                b[j++].id=i;
    
                b[j].n=a[i].b;
                b[j].type=2;
                b[j++].id=i;
            }
            discrete(2*n);
            D();
            printf("%d\n",last-1);
        }
        return 0;
    }
  • 相关阅读:
    HDU 2414 Chessboard Dance(模拟题,仅此纪念我的堕落)
    poj 1625 (AC自动机好模版,大数好模版)
    HDU 1907 John(博弈)
    如何创建一个.NET Core项目
    C#中的委托
    WEB开发者必备的7个JavaScript函数
    带你进入Angular js的大门
    程序猿的年终总结,各种版本各种残
    ASP.NET 开发人员不必担心 Node 的五大理由
    7 个 jQuery 最佳实践
  • 原文地址:https://www.cnblogs.com/Lattexiaoyu/p/2496891.html
Copyright © 2011-2022 走看看