poj 1417(并查集+简单dp)
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 2087 | Accepted: 640 |
Description
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
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
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)的更多相关文章
- POJ 1417 并查集 dp
After having drifted about in a small boat for a couple of days, Akira Crusoe Maeda was finally cast ...
- POJ - 1417 并查集+背包
思路:很简单的种类并查集,利用并查集可以将所有的人分成几个集合,每个集合又分为好人和坏人集合,直接进行背包dp判断有多少种方法可以在取了所有集合并且人数正好凑足p1个好人的方案.dp(i, j)表示前 ...
- hdu 4514 并查集+树形dp
湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Tot ...
- poj 1984 并查集
题目意思是一个图中,只有上下左右四个方向的边.给出这样的一些边, 求任意指定的2个节点之间的距离. 就是看不懂,怎么破 /* POJ 1984 并查集 */ #include <stdio.h& ...
- C - BLG POJ - 1417 种类并查集加dp(背包)
思路:刚看这道题感觉什么都不清楚,人物之间的关系一点也看不出来,都不知道怎么写,连并查集都没看出来,但是你可以仔细分析一下,当输入字符串为“yes”的时候,我们设输入的值为x和y,当x为天使是则由题可 ...
- poj1417(带权并查集+背包DP+路径回溯)
题目链接:http://poj.org/problem;jsessionid=8C1721AF1C7E94E125535692CDB6216C?id=1417 题意:有p1个天使,p2个恶魔,天使只说 ...
- poj1611(并查集简单应用)
题目链接:http://poj.org/problem?id=1611 思路: 显然是一个并查集的题,很简单,只要将一个group中的学生并在一起,最后遍历1到n-1,看有多少学生的祖先与0的祖先相等 ...
- poj 1733 并查集+hashmap
题意:题目:有一个长度 已知的01串,给出多个条件,[l,r]这个区间中1的个数是奇数还是偶数,问前几个是正确的,没有矛盾 链接:点我 解题思路:hash离散化+并查集 首先我们不考虑离散化:s[x] ...
- HDU 5575 Discover Water Tank 并查集 树形DP
题意: 有一个水槽,边界的两块板是无穷高的,中间有n-1块隔板(有高度),现有一些条件(i,y,k),表示从左到右数的第i列中,在高度为(y+0.5)的地方是否有水(有水:k = 1),问最多能同时满 ...
随机推荐
- Andrew Ng机器学习公开课笔记–Reinforcement Learning and Control
网易公开课,第16课 notes,12 前面的supervised learning,对于一个指定的x可以明确告诉你,正确的y是什么 但某些sequential decision making问题,比 ...
- SQuirreL 连接 hive
软件安装版本: hadoop-2.5.1 hbase-0.98.12.1-hadoop2 apache-hive-1.2.1-bin SQuirreL SQL Client3.7 集成步骤: 1. S ...
- jboss4.2.3建立oracle JMS应用
一.基本配置 1 增加oracle驱动文件,ojdbc6.jar,不能使用小于该版本的jdbc驱动,jboss-4.2.3.GA\server\default\lib 2 增加retrotransla ...
- phpstorm9 无法输入中文逗号句号等符号了,怎么破?
最近手贱把phpstorm 升级到了最新版,发现输入中文符号输入不了呀,全部都变成英文符号了,例如输入的逗号.句号(,.)等都被转换成了(,.) 经过各方搜索,这个在官方也说了,是个bug,JDK的b ...
- 蓝牙的L2CAP协议
1.概述 L2CAP能向上层提供面向连接的或者无连接的数据服务,拥有multiplexing capability and segmentation and reassembly operat ...
- mysql参数,蛮全的
网上有很多的文章教怎么配置MySQL服务器,但考虑到服务器硬件配置的不同,具体应用的差别,那些文章的做法只能作为初步设置参考,我们需要根据自己的情况进行配置优化,好的做法是MySQL服务器稳定运行了一 ...
- C++ 编译器内存错误 after Normal block。。。
解决 after Normal block(#908) at 0x399EC0. CRT detected that the application wrote to memory after end ...
- css3 loading效果
file:///E:/zhangqiangWork/2014/SPDbank/index.html 参考该网站 http://tobiasahlin.com/spinkit/ 查看源代码把里面的dom ...
- Echart - 地图散点图(服务网点图)的实现
Echart是百度开发的一个javascript图表库,可以流程运行于pc和移动端,底层依赖轻量级的 Canvas 类库 ZRender. ECharts 提供了常规的折线图,柱状图,散点图,饼图,K ...
- 数据库.mdf
对于.mdf文件和.ldf数据库文件, 首先打开SQL Server Management Studio Express,登陆上后,右键点击数据库,附加->选择目标文件就可以了.