• 【图论】2-sat总结


    2-sat总结

    2-sat问题,一般表现的形式为。每一个点有两种方式a,b,要么选a,要么选b。而且点点之间有一些约束关系。比如:u和v至少一个选a。那么这就是一个表达式。把a当成真,b当成假,那就是u真或v真。2-sat的题目就是这样。给定这些约束,推断是否会矛盾

    注意表达式的转化形式,(事实上就是离散数学中那几种转换方式)
    比方(u真且v真)或(u假且v假)就能够转化成(u真或v假)且(u假或v真),这样就能建立关系

    2-sat中的原理,事实上和2染色是一样的,把每一个结点拆分成一个真结点和一个假结点
    那么一个表达式(a真或b真),假设a为假,那么b必须为真。b为假a必须为真,那么就在a假b真和b假a真结点之间建边。然后跑二染色就行推断了

    一般有这么几种做法:
    推出表达式(怎样化简)。然后直接搞
    推出结点之间的真假关系,然后搞
    二分+推断(事实上这个挺easy看出来的,一般就是最大值最小化之类的)

    事实上2-sat的题目还是挺easy看出来的。问题在于怎样构造出表达式。怎样去化简表达式

    模板:

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    const int MAXNODE = 2005;
    
    struct TwoSet {
    	int n;
    	vector<int> g[MAXNODE * 2];
    	bool mark[MAXNODE * 2];
    	int S[MAXNODE * 2], sn;
    
    	void init(int tot) {
    		n = tot * 2;
    		for (int i = 0; i < n; i += 2) {
    			g[i].clear();
    			g[i^1].clear();
    		}
    		memset(mark, false, sizeof(mark));
    	}
    
    	void add_Edge(int u, int uval, int v, int vval) {
    		u = u * 2 + uval;
    		v = v * 2 + vval;
    		g[u^1].push_back(v);
    		g[v^1].push_back(u);
    	}
    
    	void delete_Edge(int u, int uval, int v, int vval) {
    		u = u * 2 + uval;
    		v = v * 2 + vval;
    		g[u^1].pop_back();
    		g[v^1].pop_back();
    	}
    
    	bool dfs(int u) {
    		if (mark[u^1]) return false;
    		if (mark[u]) return true;
    		mark[u] = true;
    		S[sn++] = u;
    		for (int i = 0; i < g[u].size(); i++) {
    			int v = g[u][i];
    			if (!dfs(v)) return false;
    		}
    		return true;
    	}
    
    	bool solve() {
    		for (int i = 0; i < n; i += 2) {
    			if (!mark[i] && !mark[i + 1]) {
    				sn = 0;
    				if (!dfs(i)){
    					for (int j = 0; j < sn; j++)
    						mark[S[j]] = false;
    					sn = 0;
    					if (!dfs(i + 1)) return false;
    				}
    			}
    		}
    		return true;
    	}
    } gao;
    
    int main() {
    
    	return 0;
    }


    HDU 3062 Party 裸题直接推断
    HDU 1824 Let's go home 化简表达式
    HDU 3622 Bomb Game 依据圆是否相交构造表达式
    HDU 3715 Go Deeper 二分+推断
    HDU 1815 Building roads 二分+构造表达式
    HDU 1816 Get Luffy Out 依据题意构造表达式
    HDU 4115 Eliminate the Conflict 把问题转化为仅仅有真假关系,进行2-sat
    POJ 2296 Map Labeler 依据相交关系(怎样推断是个问题)构造表达式
    POJ 3207 Ikki's Story IV - Panda's Trick 依据相交关系(怎样推断是个问题)构造表达式
    POJ 3648 Wedding 依据题意构造表达式
    POJ 3678 Katu Puzzle 依据题意进行表达式的化简
    POJ 3905 Perfect Election 依据题意构造表达式
    HDU 1814 Peaceful Commission 2-sat的字典序最小输出(事实上就是注意建图方式,然后让字典序小的优先染色就可以)
    HDU 4421 Bit Magic 位运算+2-sat 依据题意构造表达式
    POJ 3683 Priest John's Busiest Day 依据时间相交关系构造表达式

  • 相关阅读:
    [转]如何从无到有建立推荐系统
    sql语句查询重复值
    推荐系统开发中十个关键点整理
    mongodb中的副本集搭建实践
    Unicode对象
    5W1H
    Python中实现switch分支结构
    数据结构-跳跃表
    redis入门笔记(3)
    redis入门笔记(2)
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5184264.html
Copyright © 2020-2023  润新知