2-sat神题。。

告诉是2-sat我也完全想不到正解。

看了看题解其实一步步分析也不算很难

这个题首先是要围绕每个人是否是犯人和每句话是否是真话来思考

首先要明确的是:

1.好人不说谎话

2.说了谎话的只能是坏人

所以我们就知道了一组对称的限制条件:

好人->之前没说过谎话

之前说过谎话->坏人

如何判断一句话是否是谎话?

这个人说的话和事实不相符,这也是一种限制条件

这时我们发现还有一个很重要的条件:哪怕是坏人,也最多只说一句谎话

所以如果当前是谎话,那这个人之前所说的所有话和之后所说的所有话都是真话

所以我们在每个点应该存的是在这个点之前(包括该点)有没有说过谎话

利用上面这些限制,就可以做出这道题啦~

代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
#define M 1000010
using namespace std;
struct point{
int to,next;
}e[M<<];
int n,m,num,cnt,tim,tot,top;
int head[M],dfn[M],low[M],st[M],ans[M],co[M],pre[M];
bool vis[M];
int is_crm(int a,int b) {return a+b*n;}
//0->not
//1->yes
int word(int a,int b) {return (n<<)+a+b*m;}
//0->true
//1->false
void add(int from,int to)
{
e[++num].next=head[from];
e[num].to=to;
head[from]=num;
}
void tarjan(int x)
{
dfn[x]=low[x]=++tim;
st[++top]=x;
vis[x]=true;
for(int i=head[x];i;i=e[i].next)
{
int to=e[i].to;
if(!dfn[to])
{
tarjan(to);
low[x]=min(low[x],low[to]);
}
else if(vis[to]) low[x]=min(low[x],low[to]);
}
if(low[x]==dfn[x])
{
tot++;
while(st[top+]!=x)
{
co[st[top]]=tot;
vis[st[top]]=false;
top--;
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) pre[i]=*m+;
for(int i=;i<=m;i++)
{
int x,y,opt; scanf("%d%d%d",&x,&y,&opt);
opt^=;
add(is_crm(y,opt^),word(pre[x],));
//如果事实和他说的不是一回事,那他说的就是假话
//如果这句话是假话,在此之前的所有话皆为真话
add(word(pre[x],),is_crm(y,opt));
//如果这个人之前说过假话了,那么这句话就是真话
//他说这个人是什么就是什么
add(word(i,),is_crm(y,opt));
//如果这句话和之前都是真话,他说这个人是什么就是什么
add(is_crm(y,opt^),word(i,));
//这句话说的是反话,那这句话及之前的所有话中有反话
add(word(i,),word(pre[x],));
//如果这句话及之前的所有话皆为真,那么这句话之前所有话皆为真
add(word(pre[x],),word(i,));
//如果之前有假的,这句话及之前的话也有假的
pre[x]=i;
}
//判断是否是罪犯
for(int i=;i<=n;i++)
{
add(word(pre[i],),is_crm(i,));
add(is_crm(i,),word(pre[i],));
}
for(int i=;i<=(n+m)<<;i++)
if(!dfn[i])
tarjan(i);
for(int i=;i<=n;i++)
{
if(co[i]==co[i+n])
{
printf("Impossible");
return ;
}
else if(co[i]>co[i+n]) ans[++cnt]=i;
}
printf("%d\n",cnt);
for(int i=;i<=cnt;i++) printf("%d ",ans[i]);
return ;
}

[UOJ210]寻找罪犯的更多相关文章

  1. UOJ#210. 【UER #6】寻找罪犯 2-sat

    #210. [UER #6]寻找罪犯 链接:http://uoj.ac/problem/210 想法:2-sat模型.每个人拆点,分别表示为犯人.非犯人.每个句供词拆点,分别表示真话.假话.供词与对应 ...

  2. uoj #210. 【UER #6】寻找罪犯【2-SAT】

    首先最直观的,列一排是罪犯一排不是罪犯,对于一个条件u说v(0是1否)f罪犯,如果u不是,那么vf罪犯:如果u是,枚举他说谎的一条wg罪犯,令w(g^1)罪犯连其他条的vf 但是这样有个电度数方,会炸 ...

  3. 【UOJ #210】【UER #6】寻找罪犯

    题目描述 通过一些不可描述的方式,妹滋滋算出了 51% 的得票率,于是就她就把这个公开给了广大用户 —— UOJ 解散已成定局. 几个小时后,UOJ 创始人伏特跳蚤国王宣布辞职,即日起退出 UOJ 团 ...

  4. [LOJ6029~6052]雅礼集训 2017 选做

    Link 代码可以在loj上看我的提交记录. Day 1 [LOJ6029]市场 对于一次除法操作,若区间内所有数的减少量均相同则可视作区间减法,否则暴力递归下去.显然一个线段树节点只会被暴力递归进去 ...

  5. Tarjan/2-SAT学习笔记

    Tarjan/2-SAT Tags:图论 作业部落 评论地址 Tarjan 用来求割边或者割点,求点双联通分量或者边双联通分量 点双联通分量:两个点之间有两条点不相交的路径 边双联通分量:两个点之间有 ...

  6. Tarjan&2-SAT 总结

    \(Tarjan\)&\(2-SAT\) 标签: 知识点总结 安利XZYXZY ps:里面的部分东西来自\(Anson\)和\(yler\)和\(XZY\) 阅读体验:https://zybu ...

  7. P4478 [BJWC2018]上学路线

    Description 小B 所在的城市的道路构成了一个方形网格,它的西南角为(0,0),东北角为(N,M). 小B 家住在西南角,学校在东北角.现在有T 个路口进行施工,小B 不能通过这些路口.小B ...

  8. 2-sat问题学习记录

    如果你不知道什么是sat问题,请看以下问答. Q:sat问题是什麽?A:首先你有n个布尔变量,然后你有一个关于这n个布尔变量的布尔表达式,问你,如果让你随意给这n个布尔变量赋值,这个布尔表达式能否成立 ...

  9. TYVJ P1403 [NOIP2010]关押罪犯

    TYVJ的编译器总是要搞点岔子出来,上次是double必须用f输出而不能用lf,这次又不知道为何CE 于是去了洛谷P1525测试,AC 题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1 ...

随机推荐

  1. Android 电源管理 -- wakelock机制

    转载地址:http://blog.csdn.net/wh_19910525/article/details/8287202 Wake Lock是一种锁的机制, 只要有人拿着这个锁,系统就无法进入休眠, ...

  2. iOS-layoutSubvies和drawRect何时调用

  3. 网站速度优化模块HttpCompressionModule

    为了优化网站的访问速度,准备采用HttpCompressionModule 6对传输数据进行压缩,下载了HttpCompressionModule 6 , 并按照示例程序中的web.config配置了 ...

  4. JRE not compatible with workspace .class file compatibility: 1.7

    在进行Eclipse开发的时候,经常会遇到一些小问题,现在开始每天积累一些小问题的解决方法.出现:JRE not compatible with workspace .class file compa ...

  5. [Algorithms] Radix Sort

    Radix sort is another linear time sorting algorithm. It sorts (using another sorting subroutine) the ...

  6. delphi 事件记录

    delphi常用事件 序号 事件 描述 1. OnActive 焦点称到窗体或控件时发生 2. OnClick 鼠标单击事件 3. OnDbClick 鼠标双击事件 4. OnClose和OnClos ...

  7. iOS核心动画详解(一)

    前言 这篇文章主要是针对核心动画(Core Animation)的讲解,不涉及UIView的动画.因为内容较多,这篇文章会分为几个章节来进行介绍.本文主要是介绍核心动画的几个类之间的关系和CAAnim ...

  8. 传说中的MATLAB1.0(1984年DOS界面182K、运行良好)附下载

    传说中的MATLAB1.0(1984年DOS界面182K.运行良好)附下载 你见过 MATLAB 最早的版本吗?下载一份 MATLAB 1.0,(只有182K, 只有20来个函数) 体会一下吧.MAT ...

  9. Gson 解析多层嵌套JSON数据

    http://stackoverflow.com/questions/14139437/java-type-generic-as-argument-for-gson

  10. 2015-03-10——简析javascript对象

    对于构造函数,它是Function对象的一个实例,可以定义自己的静态成员先实例化出对象,后执行function中内部代码 静态成员:  var abc = function () {};  //既是一 ...