写了那么多模拟题这题算是最难的了QAQ

好神,,,我于是补了一下并查集。。

并查集很神。。。。。。

orz

种类并查集。。。orz

对于维护sat,我们可以这样想:

如果x和y的xor是true,那么x和y肯定不一样,那么我们有s[x]=s[y]^1

否则s[x]=s[y]

我们需要维护的是一系列的x和y之间的关系,那么我们考虑用并查集维护这个 区间!

注意这个一定是区间的概念!

因为只有区间才能满足区间性质!

比如

x xor y xor z = true

而我们得知了x xor y的值,那么我们就能知道x xor z的值!

所以x y z可以看成并查集的一条链,然后假设一开始我们只知道y xor z=true 那么连边fa[y]=z 然后 s[y]=s[x]^1

那么当我们得知x xor y=true 时,我们可以将fa[x]=y 然后s[x]=s[y]^1

而现在的图就是

x -> y -> z

我们可以尝试着压缩x到z的路径,使得得出x->z的值 即 fa[x]=z, s[x]^=s[y] 也就是说  x xor z = false

很神奇是不。。

现在我们开始重新定义s数组!

s[i]表示i到i的树根(并查集中的)的xor值

那么根据xor的性质,我们可以在路径压缩里这样写

int f=find(fa[x]); s[x]^=s[fa[x]]; p[x]=f;

那么就可以维护出s了!再一次强调,s表示的是x到树根的xor值!不是它真正的值!(否则就想我一样,一开始怎么想也想不通。。。)

然后我们在合并时,和并查集差不多,只是要维护一下s。即

fx=find(x), fy=find(y)

if(fx!=fy && (x xor y == true)) p[fx]=fy; s[fx]=s[x]^s[y]^1; //这样做的原因很简单,自己想想。。就是根据x xor y=true/false 和 x xor fx=true/false 和 y xor fy=true/false 现在只是要知道fx xor fy = ?。。注意一定不是s[fy]=...因为你看看s的定义。。。。如果是s[fy]=的话,那么p[fx]后边就都乱了。。。

x xor y==false 时也很简单 s[fx]=s[x]^s[y]

判断无解的话就是如果fx == fy 且 x到fx和y到fy的值与所给的x xor y的值不符,那么就是无解。。。

构造解也很简单。我们假设所有的根全都是true

那么问题就简单了。。。。

再路径压缩过后,每个节点到根就是一条路径,那么我们已经知道了根是true。。那么。。不用我说了吧。。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
#define mkpii make_pair<int, int>
#define pdi pair<double, int>
#define mkpdi make_pair<double, int>
#define pli pair<ll, int>
#define mkpli make_pair<ll, int>
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define error(x) (!(x)?puts("error"):0)
#define printarr2(a, b, c) for1(_, 1, b) { for1(__, 1, c) cout << a[_][__]; cout << endl; }
#define printarr1(a, b) for1(_, 1, b) cout << a[_] << '\t'; cout << endl
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
inline const int max(const int &a, const int &b) { return a>b?a:b; }
inline const int min(const int &a, const int &b) { return a<b?a:b; } const int N=1000005;
int p[N], s[N], n, m;
char c[10]; const int ifind(const int x) {
if(x==p[x]) return x;
int f=ifind(p[x]);
s[x]^=s[p[x]];
return p[x]=f;
} int main() {
read(n); read(m);
for1(i, 1, n) p[i]=i;
for1(i, 1, m) {
int x=getint(), y=getint(), fx=ifind(x), fy=ifind(y);
scanf("%s", c);
if(c[0]=='T') {
if(fx==fy && s[x]==s[y]) { puts("Impossible"); return 0; }
if(fx!=fy) p[fx]=fy, s[fx]=s[x]^s[y]^1;
}
else {
if(fx==fy && s[x]!=s[y]) { puts("Impossible"); return 0; }
if(fx!=fy) p[fx]=fy, s[fx]=s[x]^s[y];
}
}
puts("Possible");
for1(i, 1, n) ifind(i);
for1(i, 1, n) if(i==p[i]) puts("TRUE"); else s[i]?puts("FALSE"):puts("TRUE");
return 0;
}

  


2-XOR-SAT

【题目描述】

SAT(Satisfiability,可满足性)问题是著名的 NP 完全问题,它的内容是:判断由有

限个布尔变量及其“非”用“或”操作连接起来的表达式组是否可以都为 TRUE。

2-SAT 问题对 SAT 问题做了如下限制:每个表达式由两个变量构成。

XOR-SAT 问题对 SAT 问题做了如下限制:表达式仅由变量与“异或”操作构成。

2-XOR-SAT 问题包含了以上两个限制,即:有 n 个布尔变量x 1 ... x n 与 m 个双变量

异或方程

x a 1 xor x b 1 = c 1

x a 2 xor x b 2 = c 2

{

x a m xor x b m = c m

你需要判断方程组是否有解,如果有解请输出任意一组解,否则输出无解。

【输入文件】

第一行两个整数 n m

接下来m行,每行两个整数a i b i 及一个大写字符串c i ,c i 为”TRUE”或”FALSE”

【输出文件】

若无解,则输出一行”Impossible”

若有解,则第一行输出”Possible”,接下来n行输出x 1 ... x n 的值”TRUE”或”FALSE”

【样例输入】

3 2

1 2 TRUE

2 3 FALSE

【样例输出】

Possible

FALSE

TRUE

TRUE【数据范围】

30%的数据保证 n ≤ 20; m ≤ 20

100%的数据保证 1 ≤ n ≤ 100,000; 1 ≤ m ≤ 100,000

2-XOR-SAT (种类并查集)的更多相关文章

  1. NOI2001|POJ1182食物链[种类并查集 向量]

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 65430   Accepted: 19283 Description ...

  2. NOIP2010关押罪犯[并查集|二分答案+二分图染色 | 种类并查集]

    题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示 ...

  3. POJ1703Find them, Catch them[种类并查集]

    Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 42416   Accepted: ...

  4. poj1417(种类并查集+dp)

    题目:http://poj.org/problem?id=1417 题意:输入三个数m, p, q 分别表示接下来的输入行数,天使数目,恶魔数目: 接下来m行输入形如x, y, ch,ch为yes表示 ...

  5. poj1733(种类并查集+离散化)

    题目链接: http://poj.org/problem?id=1733 题意: 输入n表示有一个长度为n的0,1字符串, m表示接下来有m行输入, 接下来的m行输入中x, y, even表示第x到第 ...

  6. poj 1182:食物链(种类并查集,食物链问题)

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 44168   Accepted: 12878 Description ...

  7. pku 1703(种类并查集)

    题目链接:http://poj.org/problem?id=1703 思路;个人觉得本质上还是和带权并查集一样的,只不过多了一个MOD操作,然后就是向量关系图稍微改动一下就变成种类并查集了,对于本题 ...

  8. hdu 3038 How Many Answers Are Wrong(种类并查集)2009 Multi-University Training Contest 13

    了解了种类并查集,同时还知道了一个小技巧,这道题就比较容易了. 其实这是我碰到的第一道种类并查集,实在不会,只好看着别人的代码写.最后半懂不懂的写完了.然后又和别人的代码进行比较,还是不懂,但还是交了 ...

  9. 【进阶——种类并查集】hdu 1829 A Bug's Life (基础种类并查集)TUD Programming Contest 2005, Darmstadt, Germany

    先说说种类并查集吧. 种类并查集是并查集的一种.但是,种类并查集中的数据是分若干类的.具体属于哪一类,有多少类,都要视具体情况而定.当然属于哪一类,要再开一个数组来储存.所以,种类并查集一般有两个数组 ...

随机推荐

  1. Android常用传感器用法一览(3)

    Android 开发包标准有8个传感器: Sensor.TYPE_ACCELEROMETER o 加速度计 (X, Y, Z) m/s2 Sensor.TYPE_GYROSCOPE o 陀螺仪 (X, ...

  2. 初始化linux环境

    初始化linux环境 1. 新建用户组 addgroup admin //假定为admin用户组 2. 新建用户 useradd -d /home/work -s /bin/bash -m work ...

  3. Android 如何添加一个新的时区

    前言          欢迎大家我分享和推荐好用的代码段~~ 声明          欢迎转载,但请保留文章原始出处:          CSDN:http://www.csdn.net        ...

  4. 11g OCM 考试感悟

    11g OCM 考试感悟 PrudentWoo 累,累.真的很累.考前每天全场景的刷两遍.三遍不觉得累.总感觉练习时间不够.考中尽管时间足够.可是压力很大.尤其看到一些和平时训练不一样题目的时候,那种 ...

  5. Python将一个大文件按段落分隔为多个小文件的简单方法

    今天帮同学处理一点语料. 语料文件有点大,而且是以连续两个换行符作为段落标志,他想把它按段落分隔成多个小文件.即每3个段落组成一个新文件.因为曾经没有遇到过类似的操作,在网上找了一些类似的方法,看起来 ...

  6. 求字符串A与字符串B的最长公共字符串(JAVA)

    思路:引入一个矩阵的思想,把字符串A(长度为m)当成矩阵的行,把字符串B(长度为n)当矩阵的列.这样就构成一个m*n的矩阵.若该矩阵的节点相应的字符同样,即m[i]=n[j]时.该节点值为1:当前字符 ...

  7. 算法笔记_059:蓝桥杯练习 Anagrams问题(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 Anagrams指的是具有如下特性的两个单词:在这两个单词当中,每一个英文字母(不区分大小写)所出现的次数都是相同的.例如,“Unclea ...

  8. Tomcat日志、项目中的log4j日志、控制台——我的日志最后到底跑哪去了?

    1.Tomcat自带日志功能,即时你的项目中有log4j也不会影响到Tomcat自己记录日志. 2.你的项目中的log4j中的日志指定打印到什么地方(控制台或者文件),便会打印到什么地方,和Tomat ...

  9. 移动端页面弹幕小Demo实例说明

    代码地址如下:http://www.demodashi.com/demo/11595.html 弹幕小Demo实例地址,点击看效果 写在前面:尝试做了一下弹幕的实例,欢迎提出并指正问题 问题说明: D ...

  10. 利用 meta 标签重定向

      页面定期刷新,如果加url的,则会重新定向到指定的网页,content后面跟的是时间(单位秒),把这句话加到指定网页的<head></head>里一般也用在实时性很强的应用 ...