一、题意

好人必然说真话,坏人不一定说真话,给定N个人的言论<每人一个发言、不谈及自己>,要求指出有多少个人一定是好人,有多少个人一定是坏人。
#define 狼人 坏人
#define 村民 好人

The Werewolves" is a popular card game among young people.In the basic game, there are 2 different groups: the werewolves and the villagers.
Each player will debate a player they think is a werewolf or not. 
Their words are like "Player x is a werewolf." or "Player x is a villager.".
What we know is :
1. Villager won't lie.
2. Werewolf may lie. 
Of cause we only consider those situations which obey the two rules above. 
It is guaranteed that input data exist at least one situation which obey the two rules above.
Now we can judge every player into 3 types :
1. A player which can only be villager among all situations, 
2. A player which can only be werewolf among all situations.
3. A player which can be villager among some situations, while can be werewolf in others situations.
You just need to print out the number of type-1 players and the number of type-2 players. 
No player will talk about himself.

二、思路

假设某个局面,我们设定了N个好人及其言论,同时言论不相互矛盾——没有一个好人说谎,则同时将他们换成坏人时局面不存在相互矛盾的地方。

于是可以认为,我们无法判定谁一定是好人。但是反过来,我们可以判定一个人一定是坏人——即当他当不成好人的时候他就一定是坏人。

则可以使用"假设一个人是好人,并采信他的一切言论,如果出现矛盾则认为他言论不实,否则认为他可以成为好人"的方式进行判定。

考虑搜索时的剪枝:

1、应当将每个判定为坏人的人做特殊处理:所有指认坏人为好人的人,都是坏人。并递归的向上处理所有指认坏人为好人的人。

2、考虑每次搜索,都将有两个结果:成矛盾环或者合法:
  a、若成矛盾环,则矛盾点及以上的所有点都一定是坏人;环内除了矛盾点外所有节点为好人
  b、若合法,则链路上每个人都是好人。

#include<bits/stdc++.h>
using namespace std; #define ll long long
#define pp pair<int,int>
#define vecp vector<pp>
const int MAXN = ; pp Ga[MAXN];
vecp Gb[MAXN];
int isWolf[MAXN];
int n; int wolfpoint;
bool is_after_wolfpoint; int vis[MAXN]; bool dfs(int now)
{ // cout<<"check_dfs: "<<now<<endl;
int tar = Ga[now].first;
int isW = Ga[now].second;
vis[now] = ;
if(vis[tar] == && isW == )
{
wolfpoint = tar;
is_after_wolfpoint = ;
isWolf[now] = ;
vis[now] = ;
return false;
}
if(isWolf[tar] == && isW ==)
{
isWolf[now] = ;
is_after_wolfpoint =;
wolfpoint = tar;
vis[now] = ;
return false;
}
if(vis[tar] == && isW == )
{
bool succ = dfs(tar);
if(succ){
isWolf[now] = ;
vis[now] = ;
return true;
}else{
if(now == wolfpoint)is_after_wolfpoint = true;
if(is_after_wolfpoint)isWolf[now] = ;
else isWolf[now] = ;
vis[now] = ;
return false;
}
}
vis[now] = ;
isWolf[now] = ;
return true;
} void push_up(int now)
{
isWolf[now] = ;
int len = Gb[now].size();
for(int i=;i<len;++i)
{
int tar = Gb[now][i].first;
int isW = Gb[now][i].second;
if(isW ==)push_up(tar);
}
} void init()
{
cin>>n;
memset(isWolf,-,sizeof(isWolf));
for(int i=;i<=n+;++i)Gb[i].clear();
for(int i=;i<=n;++i)
{
int tar ;
char str[];
cin>>tar>>str;
int isW = str[] == 'w'?:;
Ga[i] = make_pair(tar,isW);
Gb[tar].push_back(make_pair(i,isW));
}
int cntt = ;
for(int i=;i<=n;++i)
{
if(isWolf[i] == )cntt++;
if(isWolf[i] != -)continue;
dfs(i);
if(isWolf[i] == )cntt++,push_up(i);
}
cout<<<<" "<<cntt<<endl; } int main()
{
cin.sync_with_stdio(false);
int t;
cin>>t;
while(t--)init();
return ;
}

HDU暑假多校第六场K-werewolf的更多相关文章

  1. HDU暑假多校第八场G-Card Game

    一.题意 给出N个卡牌,卡牌的正反两面具有两个数字,取值范围为[1,2*n],给出若干个默认正面向上的卡牌,求最小反转多少张卡牌可以使得,每张卡牌朝上的面上都有一个不同的数字,同时满足最小反转次数的反 ...

  2. HDU暑假多校第八场J-Taotao Picks Apples

    一.题意 给定一个序列,之后给出若干个修改,修改的内容为在原序列的基础上,将某一位元素的值改成给定的值<每次修改相互独立,不保存修改后的结果>.之后询问,在选择第一位元素的情况下,最长递增 ...

  3. 牛客暑假多校第六场I-Team Rocket

    一.题意 我们是穿越银河的火箭队....... 给出若干个区间,之后给出若干个点,要求对每个点求出,第一个覆盖点的区间的数量,之后用当前所有点覆盖的区间的序号的乘积结合输入的Y来生成下一位点.最后输出 ...

  4. HDU暑假多校第三场H.Monster Hunter

    一.题意 给定一个树状地图,每个树节点上有一只怪物,打死一只怪物的过程中将会消耗A点HP,打死之后将会获得B点HP.因为树状结构,所以每只怪物必须先打死父节点的怪兽之后在打死子节点的怪物.现在,给定每 ...

  5. HDU暑假多校第四场J-Let Sudoku Rotate

    一.题意 Sudoku is a logic-based, combinatorial number-placement puzzle, which is popular around the wor ...

  6. 牛客暑假多校第六场 I Team Rocket

    题意: 现在有n条火车, 每条火车都有一个运行 [ Li, Ri ], 现在有m支火箭队, 每次火箭队都会破坏这整条铁路上的一个点, 如果一条火车的运行区间[Li, Ri] 被破坏了, 那么这条火车会 ...

  7. 2020牛客多校第八场K题

    __int128(例题:2020牛客多校第八场K题) 题意: 有n道菜,第i道菜的利润为\(a_i\),且有\(b_i\)盘.你要按照下列要求给顾客上菜. 1.每位顾客至少有一道菜 2.给顾客上菜时, ...

  8. 2014多校第六场 1010 || HDU 4930 Fighting the Landlords (模拟)

    题目链接 题意 : 玩斗地主,出一把,只要你这一把对方要不了或者你出这一把之后手里没牌了就算你赢. 思路 : 一开始看了第一段以为要出很多次,实际上只问了第一次你能不能赢或者能不能把牌出尽. #inc ...

  9. 【HDU】4923 Room and Moor(2014多校第六场1003)

    Room and Moor Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) ...

随机推荐

  1. mysql 统计连续天数

    以下为例子数据 图1 图1 首先根据要求取出BeforeMeal要在7.0以下 并且 bingAfterMeal要在11.1以下 select AccountId,CreateTime from Di ...

  2. 再学UML-UML用例建模解析(三)

    2. 编写用例文档 绘制用例图只是完成了用例建模最基本也是最简单的一步,用例建模的核心在于编写用例文档,用例文档又称为用例规约或用例描述.顾名思义,用例文档是用于描述用例的文档,每一个用例对应于一个用 ...

  3. 用一个实际例子理解Docker volume工作原理

    要了解Docker Volume,首先我们需要理解Docker文件系统的工作原理.Docker镜像是由多个文件系统的只读层叠加而成.当一个容器通过命令docker run启动时,Docker会加载只读 ...

  4. python入门18 继承和多态

    继承:子类继承父类的属性和方法  class 子类名(父类1,父类2) 多态:子类重写父类的方法 判断对象是否是某个类的实例:  isinstance(object,class) 父类-汽车类 #co ...

  5. 从零开始Vue项目实战(一)-准备篇

    从前参与过一个react项目的代码编写,大神搭建的框架,我主要负责业务逻辑代码编写,现在回想起来似乎又什么都不会,现在为了巩固前端知识,决定用Vue来做这个项目的移动端网站,我本人Vue是从零开始的, ...

  6. 【转】android ListView详解

    由于google doc 很多人都打不开,故更新了源码下载地址 [源码下载]----2011-01-18 在android开发中ListView是比较常用的组件,它以列表的形式展示具体内容,并且能够根 ...

  7. Golang Failpoint 的设计与实现

    小结: 1. https://mp.weixin.qq.com/s/veIoupLjM4l5SUVC6h_Gkw Golang Failpoint 的设计与实现 原创: 龙恒 PingCAP 今天  

  8. Python实现读取json文件到excel表

    一.需求 1.'score.json' 文件内容: { "1":["小花",99,100,98.5], "2":["小王" ...

  9. vim 操作手册

    三种模式 编辑模式(i当前位置插入光标:a后一位置插入光标).控制模式(esc).可视模式(v). 编辑模式时可以正常输入. 控制模式是vim的核心,通过按键可以快速实现操作. 可视模式是进行选块操作 ...

  10. AngularJS 表格(带有CSS样式)

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...