算法:HDU 3062 Party (2-SAT入门学习)

Problem Description

有n对夫妻被邀请参加一个聚会,因为场地的问题,每对夫妻中只有1人可以 列席。在2n 个人中,某些人之间有着很大的矛盾(当然夫妻之间是没有矛盾的),有矛盾的2个人是不会同 时出现在聚会上的。有没有可能会有n 个人同时列席?

Input

n: 表示有n对夫妻被邀请 (n<= 1000) m: 表示有m 对矛盾关系 ( m < (n - 1) * (n -1)) 在接下来的m行中,每行会有4个数字,分别是 A1,A2,C1,C2 A1,A2分别表示是夫妻的编号 C1,C2 表示是妻子还是丈夫 ,0表示妻子 ,1是丈夫夫妻编号从 0 到 n -1 Output

如果存在一种情况 则输出YES 否则输出 NO

Sample Input

2 10 1 1 1

Sample Output

YES

这题只需要判断有没有解法,而不用输出方案。

【代码】

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;  

typedef long long int64;  

const int MAXN = 1010;
const int VN = MAXN*2;
const int EN = VN*VN;
int n, m;  

struct Edge{
    int v, next;
};  

struct Graph{
public:
    void init(){
        size = 0;
        memset(head, -1, sizeof(head));
    }
    void addEdge(int u, int v){
        E[size].v = v;
        E[size].next = head[u];
        head[u] = size++;
    }  

public:
    int head[VN];
    Edge E[EN];  

private:
    int size;   

}g;  

class Tow_Sat{
public:
    bool check(const Graph&g, const int n){
        scc(g, n);
        for(int i=0; i<n; ++i)
            if(belong[i*2] == belong[i*2+1])
                return false;
        return true;  

    }
private:
    int top, bcnt, idx;
    int sta[VN];
    int DFN[VN];
    int low[VN];
    int belong[VN];
    bool inStack[VN];  

    void targan(const Graph&g, const int u){
        int v;
        DFN[u] = low[u] = ++idx;
        sta[top++] = u;
        inStack[u] = true;  

        for(int e=g.head[u]; e!=-1; e=g.E[e].next){
            v = g.E[e].v;
            if(DFN[v] < 0){
                targan(g, v);
                low[u] = min(low[u], low[v]);  

            }else if(inStack[v]){
                low[u] = min(low[u], DFN[v]);  

            }
        }  

        if(DFN[u] == low[u]){
            ++bcnt;
            do{
                v = sta[--top];
                inStack[v] = false;
                belong[v] = bcnt;
            }while(u != v);  

        }
    }  

    void scc(const Graph&g, int n){
        top = bcnt = idx = 0;
        memset(DFN, -1, sizeof(DFN));
        memset(inStack, 0, sizeof(inStack));
        for(int i=0; i<2*n; ++i)
            if(DFN[i] < 0) targan(g, i);
    }  

}sat;  

int main(){
    int a,b,c,d;  

    while(~scanf("%d%d", &n, &m)){  

        g.init();
        for(int i=0; i<m; ++i){
            scanf("%d%d%d%d", &a,&b,&c,&d);
            g.addEdge(a*2+c, b*2+1-d);
            g.addEdge(b*2+d, a*2+1-c);  

        }
        if(sat.check(g, n)) puts("YES");
        else puts("NO");
    }
    return 0;
}

查看本栏目更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索算法
, description
, 个人
之间
,以便于您获取更多的相关知识。

时间: 2024-08-01 18:48:56

算法:HDU 3062 Party (2-SAT入门学习)的相关文章

React.js入门学习第一篇_javascript技巧

一.JSX介绍 ①定义 JSX=JavaScript XML,是一种在React组件内部构建标签的类XML语法.React在不使用JSX的情况下一样可以工作,但是使用JSX可以提高组件的可读性,增强JS语义,结构清晰,抽象程度高,代码模块化.因此推荐在React中使用JSX. ②特点 1.元素名首字母大写 2.符合嵌套规则 3.可以写入求值表达式 4.驼峰式命名 5.不能使用javascript原生函数的一些关键词,如for和class.需要替换成htmlFor和className ③使用方法

[转] 嵌入式入门学习法(写给惠州学院电子系学嵌入式的同学们)

我是08届惠州学院电子系的毕业生,现在从事于linux嵌入式研发工作.本人写这一篇所谓的"嵌入式入门学习法",是因为自己一开始学习嵌入式的时候,电子系里几乎没有人可以带自己入门或者教授相关学习方法,基本上都是自己摸索着学习,可想而知,这过程蛋疼的程度让人想死.所以希望通过这一年来自己的学习,整理出一条学习路线给以后电子系的师弟们作参考. 废话不多说,进入正题.首先大家应该理解两个概念,什么是处理器,什么是控制器.相信很多电子系的学生,一开始是从玩51单片机开始进入电子研发领域的,再者就

Javascript教程:入门学习正则表达式

文章简介:正则表达式30分钟入门教程. 本文目标 30分钟内让你明白正则表达式是什么,并对它有一些基本的了解,让你可以在自己的程序或网页里使用它. 如何使用本教程 别被下面那些复杂的表达式吓倒,只要跟着我一步一步来,你会发现正则表达式其实并没有你想像中的那么困难.当然,如果你看完了这篇教程之后,发现自己明白了很多,却又几乎什么都记不得,那也是很正常的--我认为,没接触过正则表达式的人在看完这篇教程后,能把提到过的语法记住80%以上的可能性为零.这里只是让你明白基本的原理,以后你还需要多练习,多使

MySQL入门学习(一)

mysql MySQL入门学习(一)  安装篇   PHP+MySQL+Linux目前已逐渐成为小型web服务器的一种经典组合.在indows环境下构筑和调试MySQL数据库是许多网站开发者的一种首选.本人在Windows98环境下初学MySQL,现将学习过程与经验总结出来供大家参考. 1.下载mysql-3.23.35-win.zip并解压: 2.运行setup.exe;选择d:\mysql,"tyical install" 3.启动mysql,有如下方法:   方法一:使用winm

MySQL入门学习(六)

mysql MySQL入门学习(六) --修改和备份.批处理   有时我们要对数据库表和数据库进行修改和删除,可以用如下方法实现: 1.增加一列: 如在前面例子中的mytable表中增加一列表示是否单身single: mysql> alter table mytable add column single char(1); 2.修改记录 将abccs的single记录修改为"y": mysql> update mytable set single='y' where nam

MySQL入门学习(五)

mysql MySQL入门学习(五) --多表操作   前面我们熟悉了数据库和数据库表的基本操作,现在我们再来看看如何操作多个表.   在一个数据库中,可能存在多个表,这些表都是相互关联的.我们继续使用前面的例子.前面建立的表中包含了员工的一些基本信息,如姓名.性别.出生日期.出生地.我们再创建一个表,该表用于描述员工所发表的文章,内容包括作者姓名.文章标题.发表日期. 1.查看第一个表mytable的内容: mysql> select * from mytable; +----------+-

MySQL入门学习(四)

mysql MySQL入门学习(四) --学习篇   上篇我们学会了如何创建一个数据库和数据库表,并知道如何向数据库表中添加记录.   那么我们如何从数据库表中检索数据呢? 1.从数据库表中检索信息 实际上,前面我们已经用到了SELECT语句,它用来从数据库表中检索信息. select语句格式一般为: SELECT 检索关键词 FROM 被检索的表 WHERE 检索条件(可选) 以前所使用的" * "表示选择所有的列. 下面继续使用我们在上篇文章中创建的表mytable: 2.查询所有

MySQL入门学习(三)

mysql MySQL入门学习(三) --学习篇   了解了一些最基本的操作命令后,我们再来学习如何创建一个数据库和数据库表. 1.使用SHOW语句找出在服务器上当前存在什么数据库: mysql> SHOW DATABASES; +----------+ | Database | +----------+ | mysql  | | test   | +----------+ 3 rows in set (0.00 sec) 2.创建一个数据库abccs mysql> CREATE DATABA

EJB入门学习代码实例

对于一个Java开发人员来说,EJB入门是一个小的关口,因为它比单纯的开发java.servlet.JSP更多 了几分系统设置上的麻烦,同时需要你更先要去了解更为广泛的知识后才能好的利用它.好了,我们就开 始我们的又一次EJB学习品罢. 本程序使用了Sun的J2EE系统(如果你在使用J2EE设置上有什么问题,可以去参见本人的代码人生之学 习品中的<J2EE使用指南>的文章).使用的例程也是J2EE中的一个最简单的例子.使用的编辑和make工 具是JBuilder.不过你也可以使用手动来用jav