POJ 1733 Parity game (disjoint-set extension field)

Topic links: Click here

Here Insert Picture Description
Here Insert Picture Description

Meaning of the questions:

Entry n n represents a length n n the 0 , 1 0,1 string, m m denotes Then there m m line input, the next m m row input x , Y , e v e n x, y, even represents x x to the first y Y the middle of characters 1 1 number is an even number; x , y , o d d x, y, odd represents x x to the first y Y the middle of characters 1 1 is odd number. If the m m first sentence k + 1 k+1 is a front for the first time with the words of contradiction, the output k k

Analysis of ideas:

x x represents x x is even in this condition, x + n x+n represents x x is an odd condition that

x , y x, y is the same

  1. in case x x is odd, y Y is an odd number
  2. in case x x is even, y Y is an even number

x , y x, y is heterogeneous

  1. in case x x is even, y Y is an odd number
  2. in case x x is odd, y Y is an even number

understanding:

Sideband rights disjoint-set: x x and y Y are related, they are in the same collection, as to what the relationship is depends on how much weight

Extension field of disjoint-set: the collection as long as a condition is true, then all remaining conditions established inevitable.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>

using namespace std;
const int N = 40010, base = N / 2;

int n, m;
int p[N];
map<int,int> mp;

int get(int x)          // 在线离散化
{
    if(mp.count(x) == 0)    mp[x] = ++n;
    return mp[x];
}

int find(int x)
{
    if(x != p[x])   p[x] = find(p[x]);
    return p[x];
}

int main()
{
    scanf("%d%d", &n, &m);
    
    n = 0;      // 用于离散化
    
    for(int i = 1; i < N; ++i)  p[i] = i;   // 初始化
    
    int res = m;
    for(int i = 1; i <= m; ++i)
    {
        int a, b;
        char op[6];
        scanf("%d%d%s", &a, &b, op);
        
        if(res != m)    continue;
        
        a = get(a - 1), b = get(b);
        
        if(op[0] == 'e')                  // 同类
        {
            if(find(a + base) == find(b))  // 有矛盾
            {
                res = i - 1;
                break;					// 数据没有输入完,可以break
            }
            p[find(a)] = find(b);
            p[find(a + base)] = find(b + base);
        }
        else                            // 异类
        {
            if(find(a) == find(b))      // 有矛盾
            {
                res = i - 1;
                break;
            }
            p[find(a)] = find(b + base);
            p[find(a + base)] = find(b);
        }
    }
    
    printf("%d\n", res);
    
    return 0;
}
Published 844 original articles · won praise 135 · Views 150,000 +

Guess you like

Origin blog.csdn.net/qq_42815188/article/details/105158828