传送门:Problem 3678

https://www.cnblogs.com/violet-acmer/p/9769406.html

难点:

  题意理解+构图

题意:

  有n个点 v[0,2......,n-1](v[i]值为0或1),边(a[i],b[i])间的权值为c[i],现在给出它们之间的一些逻辑运算的结果(比如c[1]=a[1] & b[1] = 1),逻辑运算有AND OR XOR三种,问是否存在一种满足所有条件的取值方案。

构图难点:

  如果类似 u v 1 AND这样的数据,说明u,v的1必须都选,那么就把u的0连向u的1,v的0连向v的1,这样的目的是使得推出矛盾;

  同理 u v 0 or 这样的数据,说明u,v的0必须都选,那么就把u的1连向u的0,v的1连向v的0,这样的目的是使得推出矛盾;

AC代码:

 #include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
#define pb push_back
#define mem(a,b) (memset(a,b,sizeof a))
const int maxV=1e3+;
const int maxE=1e6+; int n,m;
int a[maxE],b[maxE],c[maxE];
char op[];
int scc[*maxV];
bool vis[*maxV];
vector<int >vs;
vector<int >G[*maxV],rG[*maxV];
void addEdge(int u,int v)
{
G[u].pb(v);
rG[v].pb(u);
}
void Dfs(int u)
{
vis[u]=true;
for(int i=;i < G[u].size();++i)
{
int to=G[u][i];
if(!vis[to])
Dfs(to);
}
vs.pb(u);
}
void rDfs(int u,int k)
{
vis[u]=true;
scc[u]=k;
for(int i=;i < rG[u].size();++i)
{
int to=rG[u][i];
if(!vis[to])
rDfs(to,k);
}
}
void SCC()
{
mem(vis,false);
vs.clear();
for(int i=;i < *n;++i)
if(!vis[i])
Dfs(i);
mem(vis,false);
int k=;
for(int i=vs.size()-;i >= ;--i)
{
int to=vs[i];
if(!vis[to])
rDfs(to,++k);
}
}
void Init()
{
for(int i=;i < maxV;++i)
G[i].clear(),rG[i].clear();
}
int main()
{
scanf("%d%d",&n,&m);
Init();
for(int i=;i <= m;++i)
{
scanf("%d%d%d%s",a+i,b+i,c+i,op);
switch (op[])
{
case 'A':
if(c[i] == )
addEdge(a[i],b[i]+n),addEdge(b[i],a[i]+n);
else
addEdge(a[i]+n,a[i]),addEdge(b[i]+n,b[i]);
break;
case 'O':
if(c[i] == )
addEdge(a[i]+n,b[i]),addEdge(b[i]+n,a[i]);
else
addEdge(a[i],a[i]+n),addEdge(b[i],b[i]+n);
break;
case 'X':
if(c[i] == )
{
addEdge(a[i],b[i]+n),addEdge(b[i]+n,a[i]);
addEdge(a[i]+n,b[i]),addEdge(b[i],a[i]+n);
}
else
{
addEdge(a[i],b[i]),addEdge(b[i],a[i]);
addEdge(a[i]+n,b[i]+n),addEdge(b[i]+n,a[i]+n);
}
break;
}
}
SCC();
bool flag=false;
for(int i=;i < n;++i)
if(scc[i] == scc[i+n])
flag=true;
if(flag)
printf("NO\n");
else
printf("YES\n"); }

poj 3678(SCC+2-SAT)的更多相关文章

  1. Katu Puzzle POJ - 3678 (2 - sat)

    有N个变量X1X1~XNXN,每个变量的可能取值为0或1. 给定M个算式,每个算式形如 XaopXb=cXaopXb=c,其中 a,b 是变量编号,c 是数字0或1,op 是 and,or,xor 三 ...

  2. HDU 3062 && HDU 1824 && POJ 3678 && BZOJ 1997 2-SAT

    一条边<u,v>表示u选那么v一定被选. #include <iostream> #include <cstring> #include <cstdio> ...

  3. POJ 3678 Katu Puzzle(2-SAT,合取范式大集合)

    Katu Puzzle Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9987   Accepted: 3741 Descr ...

  4. poj 3678 Katu Puzzle(Two Sat)

    题目链接:http://poj.org/problem?id=3678 代码: #include<cstdio> #include<cstring> #include<i ...

  5. POJ 3678 Katu Puzzle(2 - SAT) - from lanshui_Yang

    Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a ...

  6. Katu Puzzle POJ - 3678(水2 - sat)

    题意: 有n个未知量,m对未知量之间的关系,判断是否能求出所有的未知量且满足这些关系 解析: 关系建边就好了 #include <iostream> #include <cstdio ...

  7. poj 3678 Katu Puzzle(2-sat)

    Description Katu Puzzle ≤ c ≤ ). One Katu ≤ Xi ≤ ) such that for each edge e(a, b) labeled by op and ...

  8. POJ 3678 Katu Puzzle 2-SAT 强连通分量 tarjan

    http://poj.org/problem?id=3678 给m条连接两个点的边,每条边有一个权值0或1,有一个运算方式and.or或xor,要求和这条边相连的两个点经过边上的运算后的结果是边的权值 ...

  9. 基础但是很重要的2-sat POJ 3678

    http://poj.org/problem?id=3678 题目大意:就是给你n个点,m条边,每个点都可以取值为0或者1,边上都会有一个符号op(op=xor or and三种)和一个权值c.然后问 ...

随机推荐

  1. nginx try_files 详解

    server { listen ; server_name localhost; index index.html index.htm index.php; root /data/wwwroot; l ...

  2. 《面向对象程序设计》第三次作业 Calculator

    c++第三次作业 Calculator git上的作业展示点这里. ps:有一点不是很明确,作业要求:将数字和符号提取出来,得到一组string,然后才将这些string存入队列中.按我的理解是需要将 ...

  3. Practice4 阅读《构建之法》6-7章

    关于第五章后面的阅读已经在Practice3中有所感悟,下面是6-7章的读书笔记. 第6章 敏捷流程这一章讲了“敏捷流程”这一概念,关于这一名词我是很陌生的,在阅读之后有了一定的理解.敏捷流程是提供了 ...

  4. 素数问题练习_HDOJ1262

    HDOJ1262_寻找素数对 和上一篇博客一样的解法,将10000以内的所有素数求出即可解题. #include<stdio.h> #include<stdlib.h> #in ...

  5. Oracle Gateways 方式创建dblink 连接 SQLSERVER数据库

    1. 安装多次 发现在同一个机器上面总出问题,所以建议找一个没有安装oracle的机器上面进行安装gateways 2. 下载oracle gateways 并且解压缩, 下载地址详情见官网. 下载的 ...

  6. [小知识] 关闭我的电脑里面的百度网盘以及修改win+e快捷键打开我的电脑

    1. 登录百度云盘客户端 设置->基本->取消在我的电脑中显示百度网盘 2. 修改win+e的默认显示 打开我的电脑. 选择查看-选项 文件夹选项修改为: 此电脑即可..

  7. 手动安装ettercap的过程

    知乎推送了一个中间人攻击的软件 ettercap 想着尝试进行一下安装学习, 如果有机会的话安全测试部分应该用的到. 1. 下载: wget https://codeload.github.com/E ...

  8. free命令详解

    free的命令详解   free命令可以显示当前系统未使用的和已使用的内存数目,还可以显示被内核使用的内存缓冲区. 语法 free [选项] 选项 -b 以Byte为单位显示内存的使用情况 -k 以K ...

  9. verilog 数据格式

    基数格式(通常为无符号数)[size]'base value size常量的位数 base数制o:8 b:2 d:10 h:16 https://wenku.baidu.com/view/f63daa ...

  10. 企业网管用linux搭建邮件服务器为公司降本增效

    在企业中,节约一分钱比挣一分钱容易得多,这是指导企业降本增效的名言之一啊,作为一名企业里的IT人员我是深有感触,尤其是IT方面,除了在互联网公司是生产力的排头兵,在制造业单位里那一般都是后勤保障部门, ...