Processing math: 100%

2-SAT模板

n-SAT 是给定多个条件,问是否有一个赋值方式使所有条件得到满足。

每个条件都有n个变量, 而2-SAT 是存在时间复杂度为O(nm)O(n+m)的做法(m是条件数)的算法的问题。

2-SAT往往是判断是否有方案使条件得到满足的一个算法。

建图:
求解2-SAT问题,需要转移到图上,对于每个变量都定义两个点分别表示true和false,用点a到点b连边表示a要选b也一要选。因此a的拓扑序一定比b要大,因为b给了a一个限制。

判断:

2-SAT有多种实现方式,用的最多的就是用tarjan来判断可行性。

tarjan来判断可行性的原理是,通过缩点之后,如果每个变量的true和false不属于一个连通分量,就说明可行。

输出方案:

因为缩点之后是深搜使得tarjan缩完点之后的编号是是倒着的拓扑序,而我们又想找到对后来限制少的点,即拓扑序大的点,所以我们找tarjan缩完点之后的编号小的点。

#include <bits/stdc++.h>
#include <stack>
#define N 2001010
using namespace std;
struct edge {
	int to, nex;
}e[N * 2];
int n, m, tot, color, cnt, flag[N], lin[N], dfn[N], low[N], belong[N], vis[N];
stack <int> s;
inline void add(int f, int t)
{
	e[++cnt].to = t;
	e[cnt].nex = lin[f];
	lin[f] = cnt;
}
void tarjan(int now)
{
 	dfn[now] = low[now] = ++tot;
 	vis[now] = 1, s.push(now);
 	for (int i = lin[now]; i; i = e[i].nex)
 	{
 		int to = e[i].to;
 		if (!dfn[to])
 			tarjan(to), low[now] = min(low[now], low[to]);
 		else if (vis[to])
 			low[now] = min(low[now], dfn[to]);
 	}
 	if (dfn[now] == low[now])
 	{
 		++color;
 		while (!s.empty())
 		{
 			int v = s.top(); s.pop();
 			belong[v] = color, vis[v] = 0;
 			if (v == now) break;
 		}
 	}
}
int main()
{
 	scanf("%d%d", &n, &m);
 	while (m--)
 	{
 		int i, a, j, b;		
 		scanf("%d%d%d%d", &i, &a, &j, &b);
 		add(j + (b ^ 1) * n, i + a * n);
  		add(i + (a ^ 1) * n, j + b * n);
 	}//就是xi为a时, xj一定 不为b,反过来xj一定不为b时,xi并不满足一定为a,因此要从j+(b^1)*n连向i+a*n 
  	for (int i = 1; i <= n * 2; i++)
  		if (!dfn[i])     	
 		 	tarjan(i);   	
  	for (int i = 1; i <= n; i++)
 		if (belong[i] == belong[i + n])	
 			printf("IMPOSSIBLE\n"), exit(0);
 	printf("POSSIBLE\n");	//最后我们要选对后来限制小的点,所以就是要选拓扑序大的,也就是belong小的 
 	for (int i = 1; i <= n; i++)
 	{						
 		if (belong[i] < belong[i + n])//无相等情况 
 			printf("1 ");	
 		else				
 			printf("0 ");	
 	}						
 	return 0;				
}
posted @   DAGGGGGGGGGGGG  阅读(239)  评论(0编辑  收藏  举报
编辑推荐:
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
· AI与.NET技术实操系列:使用Catalyst进行自然语言处理
· 分享一个我遇到过的“量子力学”级别的BUG。
· Linux系列:如何调试 malloc 的底层源码
阅读排行:
· JDK 24 发布,新特性解读!
· C# 中比较实用的关键字,基础高频面试题!
· .NET 10 Preview 2 增强了 Blazor 和.NET MAUI
· Ollama系列05:Ollama API 使用指南
· 为什么AI教师难以实现
点击右上角即可分享
微信分享提示