调了将近两天终于过了这道并查集 + 背包DP。。。!!!O(∩_∩)O~~
http://poj.org/problem?id=1417
题意就是有p1+p2个人,其中p1个好人,p2个坏人,好人说真话,坏人说假话。有n个关系X Y yes表示X说Y是好人,这样我们就知道X和Y都是好人或者都是坏人;X Y no表示X说Y是坏人,这就代表或者X是好人,Y是坏人,或者Y是好人而X是坏人。
我们将一个人拆成两个,X表示好人X,X+p1+p2表示坏人X,接着根据关系用并查集合并。这样就得到了一些集合,这些集合一定是两两相对的就是比如一个集合{X, Y +p1+p2, Z},那么就一定有一个集合是{X+p1+p2, Y, Z+p1+p2}。。。
接下来我们需要从这些集合中选择一些集合,使得他们的好人数之和为p1。在这里我们用背包的思想dp[i][j],表示前i个集合有j个好人的方案数。注意这里必定会选一个集合或者和他相对是集合,不可能都选,也不可能都不选。!!!!(QAQ卡在这里了。。。)
最后需要输出方案,根据dp的值dfs找即可。。
//#pragma comment(linker,"/STACK:1024000000,1024000000")
#include