您的位置:首页 > 其它

BZOJ 2303 [Apio2011]方格染色

2017-03-06 17:15 316 查看
易或方程+带权并查集

我好SB啊,挂题解吧。。。。。。

http://www.cnblogs.com/HHshy/p/5840018.html

#include<cstdio>
#include<cstring>
#define N 2333333
#define MOD 1000000000
#define R register
using namespace std;
namespace runzhe2000
{
int read()
{
R int r = 0; R char c = getchar();
for(; c < '0' || c > '9'; c = getchar());
for(; c >='0' && c <='9'; r = r*10+c-'0', c = getchar());
return r;
}
int n, m, k, f
, fv
, vis
, X
, Y
, V
;
int find(R int x)
{
if(f[x] == x) return x;
else
{
R int y = find(f[x]);
fv[x] ^= fv[f[x]];
return f[x] = y;
}
}
int solve()
{
R int x, y, v, fx, fy;
for(R int i = 1; i <= n+m; i++) f[i] = i; memset(fv, 0, sizeof(fv));
for(R int i = 1; i <= k; i++)
{
x = X[i]; y = Y[i] + n; v = V[i];
if(x == 1 || y == n+1) continue;
fx = find(x);
fy = find(y);
R int w = v ^ vis[1] ^ (x%2==0&&y%2==0?1:0);
if(fx != fy)
{
f[fx] = fy;
fv[fx] = w^fv[x]^fv[y];
}
else if((fv[x]^fv[y]) != w) return 0;
}
for(R int i = 1; i <= k; i++)
{
x = X[i]; y = Y[i] + n; v = V[i];
if(x == 1 || y == n+1)
{
if(y == n+1) y = 1;
x == 1 ? x = y : 0;
R int fx = find(x);
if(vis[fx] != -1)
{
if((v ^ vis[fx]) != fv[x]) return 0;
}
else vis[fx] = v ^ fv[x];
}
}
R int ans = 1;
for(R int i = n+m; i >= 1; i--)
{
R int fi = find(i);
if(i == fi && vis[i] == -1 && i != n+1) (ans <<= 1) %= MOD;
}
return ans;
}
void main()
{
n = read(), m = read(), k = read();
for(int i = 1; i <= k; i++) X[i] =read(), Y[i] = read(), V[i] = read();
int ans = 0;
memset(vis, -1, sizeof(vis)); vis[1] = 0; (ans += solve()) %= MOD;
memset(vis, -1, sizeof(vis)); vis[1] = 1; (ans += solve()) %= MOD;
printf("%d\n",ans);
}
}
int main()
{
runzhe2000::main();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: