#4887. 核战·桃仁杀
核战·桃仁杀
Background
“核战·桃仁杀”(game)
【题目描述】
n位同学(编号从1到n)在玩一个叫作“核战·桃仁杀”的游戏,游戏规则是这样的:初始时,每人会摸取一张确认自己身份的卡片,身份只有两种类型——“好人” 或者 “坏人”(初始时只有他们自己知道自己的真实身份)。
接下来玩m轮游戏,每一轮都会由系统产生一对数字i和j(1≤i,j≤n, i ≠ j),编号为i的同学可以查看到编号为j的同学的真实身份,并汇报同学j的身份。汇报规则如下:
若 i是好人,j是好人,则i会汇报j是好人;
若 i是好人,j是坏人,则i会汇报j是坏人;
若 i是坏人,j是好人,则i会汇报j是坏人;
若 i是坏人,j是坏人,则i会汇报j是好人。
当他们在玩这个游戏的时候,一旁的禾木记录下了上述m轮信息。禾木想知道,根据这 m 轮信息,可以推测这 n位同学中“坏人”最多有多少人?请你帮助他解决这个问题。
【输入格式】
第一行,输入两个整数n和m,以一个空格分隔,分别表示玩游戏的人数和游戏轮数(1≤n ≤2×10^5^, 0≤m≤5×10^5^)。
接下来m 行,每行包含一轮信息 “i j c”,其中i和j是两个各不相同的整数,c是一个字符串,表示编号为i的同学汇报了编号为j的同学的信息(1≤i,j≤n, i≠j,c为good或bad,当c为good时,表示i汇报j是好人;当c为bad时,表示i汇报j是坏人)。
【输出格式】
如果这 m 轮汇报信息无法得到一种合法的情况(有可能是因为有的同学没有按照游戏规则汇报信息),那么输出整数−1。否则,输出一个整数,表示满足 m 轮要求的情况下,“坏人”的最多人数。
【样例1输入】
5 4
1 3 good
2 5 good
2 4 bad
3 4 bad
【样例1输出】
4
【样例1解释】
坏人人数最多的一种情况是:1、2、3和5是坏人,4是好人。
【样例2输入】
2 2
1 2 bad
2 1 good
【样例2输出】
-1
【样例2解释】
若 1汇报了2是坏人,则以下两种情况中必然有一个是成立的:
① 1是好人,2是坏人;
② 1是坏人,2是好人。
这两种情况下,2 都不可能会汇报1是好人,因此这是一种不合法的情况。
【样例3】
见选手目录下的game/game3.in与game/game3.ans(见CCF官方网站)。
【数据范围与提示】
共20组测试数据,其中:
第1 至第4组测试数据,n,m≤10;
第5 至第10组测试数据,n,m≤1000;
第11组测试数据,n=10000, m=0;
第12组测试数据,n=10000, m=9999,所有轮中的i 都为1;
第13 至第20组测试数据,1≤n≤2×10^5^, 0≤m≤5×10^5^。
提示
将问题转换成图论模型。若 i汇报j是好人,则在节点i和j之间连一条权值为0的双向边;若i汇报j是坏人,则在节点i和j之间连一条权值为1的双向边。然后对图中的n个节点进行“染色”操作,染色共需两种颜色,设为“黑色”(用1表示)和“白色”(用0 表示)。
对于当前节点u,设与其邻接的一条边的权值为w,对应的另一个节点编号为v,则依次进行如下判断。
(1)若节点v没有访问过,则分为如下两种情况。
● 若 w=1,则节点v染与节点u相反的颜色。
● 若 w=0,则节点v染与节点u相同的颜色。
(2)若节点v已访问过,则分为如下两种情况。
● 若 w=1且节点u和节点v的颜色相同,说明是不合法的情况,直接退出。
● 若 w=0且节点u和节点v的颜色不同,说明是不合法的情况,直接退出。
你可以使用dfs()函数进行染色操作。
对于同一个连通块,运行一遍dfs()函数能够得到连通块内黑色的节点个数和白色的节点个数,两者的较大值就是该连通块内对应的“坏人”的最大数量。对每一个连通块中计算出来的“坏人”最大数量进行累加,就能够得到“坏人”的最大人数了。
Limitation
1s, 1024KiB for each test case.