zoukankan      html  css  js  c++  java
  • BZOJ2303 APIO2011方格染色(并查集)

      比较难想到的是将题目中的要求看做异或。那么有ai,j^ai+1,j^ai,j+1^ai+1,j+1=1。瞎化一化可以大胆猜想得到a1,1^a1,j^ai,1^ai,j=(i-1)*(j-1)&1。也就是说,确定第一行和第一列的颜色,就可以确定整个矩阵。现在如果没有已填的格子的限制,答案就是2n+m-1

      然后考虑已填格子。假设固定了a1,1,那么其影响到的就是a1,j和ai,1。即要求两者相同或不同。于是可以把每个格子的染色情况拆成两个点,根据已填格子将其连边,同一连通块内的点只要选择一个就必须全部选择。那么方案数就是2连通块个数/2。注意特判第一行或第一列格子已填的情况。

      细节比较麻烦,写完也不知道自己在干啥。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define P 1000000000
    #define N 100010
    int n,m,k,fa[N<<2],color[N<<2];
    struct data{int x,y,c;
    }a[N];
    int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    int solve(int c)
    {
        memset(color,0,sizeof(color));
        for (int i=1;i<=(n+m-2<<1);i++) fa[i]=i;
        for (int i=1;i<=k;i++)
        if (a[i].x!=1&&a[i].y!=1)
        if ((a[i].c==c)^(((a[i].x-1)&1)*(a[i].y-1)&1)) fa[find((a[i].x-1<<1)-1)]=find((n+a[i].y-2<<1)-1),fa[find(a[i].x-1<<1)]=find(n+a[i].y-2<<1);
        else fa[find((a[i].x-1<<1)-1)]=find(n+a[i].y-2<<1),fa[find(a[i].x-1<<1)]=find((n+a[i].y-2<<1)-1);
        int cnt=0;
        for (int i=1;i<=n+m-2;i++) if (find((i<<1)-1)==find(i<<1)) return 0;
        for (int i=1;i<=k;i++)
        {
            if (a[i].x==1&&a[i].y==1){if (a[i].c!=c) return 0;}
            else
            {
                if (a[i].y==1)
                {
                    if (color[find((a[i].x-1<<1)-a[i].c)]!=-1) color[find((a[i].x-1<<1)-a[i].c)]=1;else return 0;
                    if (color[find((a[i].x-1<<1)-(a[i].c^1))]!=1) color[find((a[i].x-1<<1)-(a[i].c^1))]=-1;else return 0;
                }
                if (a[i].x==1)
                {
                    if (color[find((n+a[i].y-2<<1)-a[i].c)]!=-1) color[find((n+a[i].y-2<<1)-a[i].c)]=1;else return 0;
                    if (color[find((n+a[i].y-2<<1)-(a[i].c^1))]!=1) color[find((n+a[i].y-2<<1)-(a[i].c^1))]=-1;else return 0;
                }
            }
        }
        for (int i=1;i<=(n+m-2<<1);i++)
        if (find(i)==i&&!color[i]) cnt++;
        cnt>>=1;
        int ans=1;while (cnt--) ans=(ans<<1)%P;
        return ans;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj2303.in","r",stdin);
        freopen("bzoj2303.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read(),m=read(),k=read();
        for (int i=1;i<=k;i++) a[i].x=read(),a[i].y=read(),a[i].c=read();
        cout<<(solve(0)+solve(1))%P;
        return 0;
    }
  • 相关阅读:
    118/119. Pascal's Triangle/II
    160. Intersection of Two Linked Lists
    168. Excel Sheet Column Title
    167. Two Sum II
    172. Factorial Trailing Zeroes
    169. Majority Element
    189. Rotate Array
    202. Happy Number
    204. Count Primes
    MVC之Model元数据
  • 原文地址:https://www.cnblogs.com/Gloid/p/9560839.html
Copyright © 2011-2022 走看看