True Liars
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 2087   Accepted: 640

Description

After having drifted about in a small boat for a couple of days, Akira Crusoe Maeda was finally cast ashore on a foggy island. Though he was exhausted and despaired, he was still fortunate to remember a legend of the foggy island,
which he had heard from patriarchs in his childhood. This must be the island in the legend. In the legend, two tribes have inhabited the island, one is divine and the other is devilish, once members of the divine tribe bless you, your future is bright and
promising, and your soul will eventually go to Heaven, in contrast, once members of the devilish tribe curse you, your future is bleak and hopeless, and your soul will eventually fall down to Hell.




In order to prevent the worst-case scenario, Akira should distinguish the devilish from the divine. But how? They looked exactly alike and he could not distinguish one from the other solely by their appearances. He still had his last hope, however. The members
of the divine tribe are truth-tellers, that is, they always tell the truth and those of the devilish tribe are liars, that is, they always tell a lie.




He asked some of them whether or not some are divine. They knew one another very much and always responded to him "faithfully" according to their individual natures (i.e., they always tell the truth or always a lie). He did not dare to ask any other forms of
questions, since the legend says that a devilish member would curse a person forever when he did not like the question. He had another piece of useful informationf the legend tells the populations of both tribes. These numbers in the legend are trustworthy
since everyone living on this island is immortal and none have ever been born at least these millennia.




You are a good computer programmer and so requested to help Akira by writing a program that classifies the inhabitants according to their answers to his inquiries.

Input

The input consists of multiple data sets, each in the following format :




n p1 p2

xl yl a1

x2 y2 a2

...

xi yi ai

...

xn yn an



The first line has three non-negative integers n, p1, and p2. n is the number of questions Akira asked. pl and p2 are the populations of the divine and devilish tribes, respectively, in the legend. Each of the following n lines has two integers xi, yi and one
word ai. xi and yi are the identification numbers of inhabitants, each of which is between 1 and p1 + p2, inclusive. ai is either yes, if the inhabitant xi said that the inhabitant yi was a member of the divine tribe, or no, otherwise. Note that xi and yi
can be the same number since "are you a member of the divine tribe?" is a valid question. Note also that two lines may have the same x's and y's since Akira was very upset and might have asked the same question to the same one more than once.




You may assume that n is less than 1000 and that p1 and p2 are less than 300. A line with three zeros, i.e., 0 0 0, represents the end of the input. You can assume that each data set is consistent and no contradictory answers are included.



Output

For each data set, if it includes sufficient information to classify all the inhabitants, print the identification numbers of all the divine ones in ascending order, one in a line. In addition, following the output numbers, print
end in a line. Otherwise, i.e., if a given data set does not include sufficient information to identify all the divine members, print no in a line.

Sample Input

2 1 1
1 2 no
2 1 no
3 2 1
1 1 yes
2 2 yes
3 3 yes
2 2 1
1 2 yes
2 3 no
5 4 3
1 2 yes
1 3 no
4 5 yes
5 6 yes
6 7 no
0 0 0

Sample Output

no
no
1
2
end
3
4
5
6
end
题意:有A和B两个部落,A部落的人都是好人,始终讲实话,而B部落的人都是坏淫,都说谎话,题目给出n,代表问题的个数,给出p1和p2代表两个部落的人,然后a,b,ch,如果a说b是好人则ch是yes,否则是no,然后根据问题得出的回答能不能确定谁是好人,谁是坏淫,若可以且情况唯一,则按顺序输出好人的编号,否则输出no
分析:对于a,b,yes,若a是好人,则b一定是好人,若a是坏淫,则b一定是坏人,对于a,b,no,若a是好人,则b是坏人,若a是坏人,则a在说谎,b则是好人,所以yes的时候a和b在同一个集合中,no的时候a和b不在一个集合中,所以,应该用并查集路径压缩判断,得出每个集合的两类人数,然后利用dp[i][j]记录到第i个集合的时候有j个好人的情况个数,若为一种情况,则用pre[i][j]记录路径
程序:
#include"cstdio"
#include"cstring"
#include"cstdlib"
#include"cmath"
#include"string"
#include"map"
#include"cstring"
#include"iostream"
#include"algorithm"
#include"queue"
#include"stack"
#define inf 0x3f3f3f3f
#define M 1000
#define eps 1e-8
#define INT int
using namespace std;
int f[M],h[M],num[M],sum[M],pre[M][M],s[M];
int dp[M][M];
struct node
{
int a,b;
}belong[M],mark[M];
int finde(int x)
{
if(x!=f[x])
{
int y=f[x];
f[x]=finde(f[x]);
sum[x]=(sum[x]+sum[y])%2;
}
return f[x];
}
void make(int a,int b,int k)
{
int x=finde(a);
int y=finde(b);
if(x<y)
{
f[y]=x;
sum[y]=(2+sum[y]+sum[a]+k-sum[b])%2;
h[x]+=h[y];
}
else if(y<x)
{
f[x]=y;
sum[x]=(2+sum[x]+sum[b]+k-sum[a])%2;
h[y]+=h[x];
}
}
int main()
{
int n,p1,p2;
while(scanf("%d%d%d",&n,&p1,&p2),n||p1||p2)
{
memset(belong,0,sizeof(belong));
memset(mark,0,sizeof(mark));
for(int i=1;i<=p1+p2;i++)
{
f[i]=i;
h[i]=1;
sum[i]=0;
}
for(int i=1;i<=n;i++)
{
int a,b;
char ch[6];
scanf("%d%d%s",&a,&b,ch);
if(strcmp(ch,"yes")==0)
make(a,b,0);
else
make(a,b,1);
}
int cnt=0;
for(int i=1;i<=p1+p2;i++)
{
if(f[i]==i)
{
num[i]=++cnt;
}
}
for(int i=1;i<=p1+p2;i++)
{
f[i]=finde(i);
if(sum[i]==0)
belong[num[f[i]]].a++;
else
belong[num[f[i]]].b++;
}
//for(int i=1;i<=cnt;i++)
//printf("%d %d\n",belong[i].a,belong[i].b);
memset(dp,0,sizeof(dp));
memset(pre,-1,sizeof(pre));
dp[0][0]=1;
for(int i=1;i<=cnt;i++)
{
for(int j=p1;j>=0;j--)
{
if(j-belong[i].a>=0)
dp[i][j]+=dp[i-1][j-belong[i].a];
if(j-belong[i].b>=0)
dp[i][j]+=dp[i-1][j-belong[i].b]; if(dp[i][j]==1)
{
if(j-belong[i].a>=0&&dp[i-1][j-belong[i].a]==1)
{
pre[i][j]=1;
}
if(j-belong[i].b>=0&&dp[i-1][j-belong[i].b]==1)
{
pre[i][j]=2;
}
}
}
}
if(dp[cnt][p1]!=1)
{
printf("no\n");
}
else
{
int j=p1;
for(int i=cnt;i>=1;i--)
{
if(pre[i][j]==1)
{
//printf("%d\n",belong[i].a);
j-=belong[i].a;
mark[i].a++;
}
else
{
//printf("%d\n",belong[i].b);
j-=belong[i].b;
mark[i].b++;
}
}
int cot=0;
for(int i=1;i<=p1+p2;i++)
{
if(mark[num[f[i]]].a&&sum[i]==0)
{
s[cot++]=i;
}
else if(mark[num[f[i]]].b&&sum[i]==1)
{
s[cot++]=i;
}
}
for(int i=0;i<cot;i++)
printf("%d\n",s[i]);
printf("end\n");
}
}
return 0;
}

poj 1417(并查集+简单dp)的更多相关文章

  1. POJ 1417 并查集 dp

    After having drifted about in a small boat for a couple of days, Akira Crusoe Maeda was finally cast ...

  2. POJ - 1417 并查集+背包

    思路:很简单的种类并查集,利用并查集可以将所有的人分成几个集合,每个集合又分为好人和坏人集合,直接进行背包dp判断有多少种方法可以在取了所有集合并且人数正好凑足p1个好人的方案.dp(i, j)表示前 ...

  3. hdu 4514 并查集+树形dp

    湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tot ...

  4. poj 1984 并查集

    题目意思是一个图中,只有上下左右四个方向的边.给出这样的一些边, 求任意指定的2个节点之间的距离. 就是看不懂,怎么破 /* POJ 1984 并查集 */ #include <stdio.h& ...

  5. C - BLG POJ - 1417 种类并查集加dp(背包)

    思路:刚看这道题感觉什么都不清楚,人物之间的关系一点也看不出来,都不知道怎么写,连并查集都没看出来,但是你可以仔细分析一下,当输入字符串为“yes”的时候,我们设输入的值为x和y,当x为天使是则由题可 ...

  6. poj1417(带权并查集+背包DP+路径回溯)

    题目链接:http://poj.org/problem;jsessionid=8C1721AF1C7E94E125535692CDB6216C?id=1417 题意:有p1个天使,p2个恶魔,天使只说 ...

  7. poj1611(并查集简单应用)

    题目链接:http://poj.org/problem?id=1611 思路: 显然是一个并查集的题,很简单,只要将一个group中的学生并在一起,最后遍历1到n-1,看有多少学生的祖先与0的祖先相等 ...

  8. poj 1733 并查集+hashmap

    题意:题目:有一个长度 已知的01串,给出多个条件,[l,r]这个区间中1的个数是奇数还是偶数,问前几个是正确的,没有矛盾 链接:点我 解题思路:hash离散化+并查集 首先我们不考虑离散化:s[x] ...

  9. HDU 5575 Discover Water Tank 并查集 树形DP

    题意: 有一个水槽,边界的两块板是无穷高的,中间有n-1块隔板(有高度),现有一些条件(i,y,k),表示从左到右数的第i列中,在高度为(y+0.5)的地方是否有水(有水:k = 1),问最多能同时满 ...

随机推荐

  1. Git相关的项目

    1.posh-git Git的PowerShell扩展 项目地址: https://github.com/dahlbyk/posh-git 可以用psget快速安装扩展模块,psget下载安装地址 h ...

  2. JVM内存配置

    JVM内存主要分为两个部分,分别是PermanentSapce和HeapSpace. PermantSpace主要负责存放加载的Class类级对象如class本身,method,field等反射对象, ...

  3. 实例讲述PHP面向对象的特性;;;php中const与define的使用区别

    php中const与define的使用区别 1.const:类成员变量定义,一旦定义且不能改变其值. define:定义全局常量,在任何地方都可以访问.2.define:不能在类中定义,而const可 ...

  4. https centos6 and 7

    keytool -printcert -sslserver 10.10.192.90:8443 -rfc >nexus.crt 通过  openssl 将 证书转换为 .pem格式的 通过以下命 ...

  5. Java实验报告二:Java面向对象程序设计

    Java实验报告二:Java面向对象程序设计                                                                               ...

  6. Java科普之加密算法

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 加密比较复杂,但今天公司有需求,就稍微再研究一下,方式只有两种,对称加密和非对称加密.对称加密是指加 ...

  7. 【C51】单片机定时器介绍

    标准51架构的单片机有2个定时器 :T0  和  T1,他们2个的用法几乎一样.下面主要讲T0定时器的用法. 初步认知 定时器 和 计数器 都是单片机中同一个模块.他们的实质都是: 加法存储计数器.对 ...

  8. PHP 日期比较

    $temptime = mktime(8,2,12,4,4,2014);$dt1 = date("Y-m-d",time());$dt2 = date("Y-m-d&qu ...

  9. cdecl和stdcall调用约定-汇编演示

    . .model flat, stdcall .stack ExitProcess PROTO, dwExitCode:DWORD .data val2 sdword result dword ? . ...

  10. 美国VPS - DigitalOcean 推荐创业团队使用

    初创公司DigitalOcean在美国正迅速成为一个家喻户晓的公司.每月5美元,该公司就可以让你享受到一个虚拟的私有服务器(或者说droplets,很多公司都这么称呼它).该公司的联合创始人兼首席执行 ...