Codeforces-766D-The Door Problem(2-SAT-并查集解)

题目链接:Codeforces-766D-The Door Problem

首先可以知道一个钥匙只能使用0或1次。使用多次时与使用0或1次等效。

如果一个门状态是1,那么与这个门关联的两个钥匙要么都使用1次,要么都使用0次。

如果一个门状态是0,那么一个钥匙使用1次,另一个钥匙使用0次。

用u表示钥匙u使用0次,用u+m表示钥匙u使用1次。

然后使用并查集维护。如果u和u+m在同一个集合里,则出现矛盾。否则输出YES。


#include
#define mp make_pair
#define pr pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
vector k[maxn],d[maxn];
int r[maxn],father[maxn<<1];
int n,m;
int f(int x)
{
	if(x==father[x])	return x;
	father[x]=f(father[x]);
	return father[x];
}

void Union(int x,int y)
{
	x=f(x);y=f(y);
	father[x]=y;
}

int main()
{
	vector k1,k2;
	cin>>n>>m;
	for(int i=0;i>r[i];
	int x,tmp;
	for(int i=0;i>x;
		for(int j=0;j>tmp;
			k[i].push_back(tmp);
			d[tmp].push_back(i);
		}
		if(x==0)	--m;
		else ++i;
	}
	for(int i=1;i<=n;i++)
	{
		if(r[i])	Union(d[i][0],d[i][1]),Union(d[i][0]+m,d[i][1]+m);
		else Union(d[i][0],d[i][1]+m),Union(d[i][0]+m,d[i][1]);
	}
	int tt=f(0);
	for(int i=0;i


你可能感兴趣的:(2-SAT)