题意:有一个岛上住着一些神和魔,并且已知神和魔的数量,现在已知神总是说真话,魔总是说假话,有 n 个询问,问某个神或魔(身份未知),问题是问某个是神还是魔,根据他们的回答,问是否能够确定哪些是神哪些是魔。

对于这些问题,我们只需要发现,如果回答对方是魔,那么即可以判断出这两个不是同一种族,而如果回答对方是神,那么说明这两个是同一种族,那么就可以用带权并查集合并这些神和魔,然后记录两种分别多少个,这样当所有询问都处理完时我们就可以得到一系列的集合,每个集合分别有它的两个种族的人数,但是此时对于每个集合,这两个人数我们并不知道分别哪个是神哪个是魔,这时候就需要用到0/1背包的方法, dp[i][j] 代表处理到第 i 个集合时共 j 个人数(神或魔)的情况数,它从 dp[i-1][j-num1[i]] 和 dp[i-1][j-num2[i]] 转移过来,这里 num1、num2 就是一个并查集的两种人数。转移时顺便记录它是从哪个值转移过来的,便于最后输出。这样只要最后处理完所有集合时正好神的人数或魔的人数的情况正好是一种,那么就说明可行。按照记录的转移遍历回去输出所有解就行。加了个小优化就是当某个集合的两种数量相等的时候,直接可以判断否,因为这时这两个数量等效。

 #include<stdio.h>
#include<string.h> int fa[],num[],n,num1[],num2[],p[],dp[][],fat[][],num3[];
int p1,p2;
char s[]; int mmax(int a,int b){
return a>b?a:b;
} void init(){
for(int i=;i<=p1+p2;i++){
fa[i]=i;
num1[i]=;
}
memset(num,,sizeof(num));
memset(num2,,sizeof(num2));
} int find(int x){
int r=x,t1,t2,c=;
while(r!=fa[r]){
c+=num[r];
r=fa[r];
}
while(r!=x){
t1=fa[x];
t2=c-num[x];
num[x]=c%;
fa[x]=r;
x=t1;
c=t2;
}
return r;
} int main(){
while(scanf("%d%d%d",&n,&p1,&p2)!=EOF&&n!=||p1!=||p2!=){
int i;
init();
for(i=;i<=n;i++){
int a,b,v;
scanf("%d%d%s",&a,&b,s);
if(s[]=='y')v=;
else v=;
int x=find(a),y=find(b);
if(x!=y){
num[x]=((num[b]+v-num[a])%+)%;
if(num[x]==){
num1[y]+=num1[x];
num2[y]+=num2[x];
}
else{
num1[y]+=num2[x];
num2[y]+=num1[x];
}
fa[x]=y;
}
}
bool f=;
if(p1==p2)printf("no\n");
else{
int cnt=,j;
for(i=;i<=p1+p2;i++){
if(fa[i]==i){
p[++cnt]=i;
if(num1[i]==num2[i])f=;
}
}
if(f){
memset(dp,,sizeof(dp));
dp[][]=;
for(i=;i<=cnt;i++){
for(j=;j<=p1;j++){
if(dp[i-][j]){
dp[i][j+num1[p[i]]]+=dp[i-][j];
fat[i][j+num1[p[i]]]=j;
dp[i][j+num2[p[i]]]+=dp[i-][j];
fat[i][j+num2[p[i]]]=j;
}
}
}
if(dp[cnt][p1]!=)f=;
}
if(!f)printf("no\n");
else{
int father=p1;
for(i=cnt;i>=;i--){
if(father-fat[i][father]==num1[p[i]]){
num3[p[i]]=;
}
else num3[p[i]]=;
father=fat[i][father];
}
for(i=;i<=p1+p2;i++){
int x=find(i);
if(num[i]==num3[x])printf("%d\n",i);
}
printf("end\n");
}
}
}
return ;
}

poj1417 带权并查集+0/1背包的更多相关文章

  1. poj1417 带权并查集 + 背包 + 记录路径

    True Liars Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2713   Accepted: 868 Descrip ...

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

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

  3. POJ 1703 Find them, Catch them(带权并查集)

    传送门 Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 42463   Accep ...

  4. [NOIP摸你赛]Hzwer的陨石(带权并查集)

    题目描述: 经过不懈的努力,Hzwer召唤了很多陨石.已知Hzwer的地图上共有n个区域,且一开始的时候第i个陨石掉在了第i个区域.有电力喷射背包的ndsf很自豪,他认为搬陨石很容易,所以他将一些区域 ...

  5. poj1984 带权并查集(向量处理)

    Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 5939   Accepted: 2 ...

  6. 【BZOJ-4690】Never Wait For Weights 带权并查集

    4690: Never Wait for Weights Time Limit: 15 Sec  Memory Limit: 256 MBSubmit: 88  Solved: 41[Submit][ ...

  7. 洛谷OJ P1196 银河英雄传说(带权并查集)

    题目描述 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦 创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山 ...

  8. poj1611 带权并查集

    题意:病毒蔓延,现在有 n 个人,其中 0 号被认为可能感染,然后给出多个社交圈,如果某个社交圈里有人被认为可能被感染,那么所有这个社交圈里的人都被认为可能被感染,现在问有多少人可能被感染. 带权并查 ...

  9. hdu 1829-A Bug's LIfe(简单带权并查集)

    题意:Bug有两种性别,异性之间才交往, 让你根据数据判断是否存在同性恋,输入有 t 组数据,每组数据给出bug数量n, 和关系数m, 以下m行给出相交往的一对Bug编号 a, b.只需要判断有没有, ...

随机推荐

  1. Oracle常用的函数

    1.常用的函数分为五大类: 字符函数.数字和日期函数.数字函数.转换函数.混合函数 2.字符函数 字符函数主要用于修改字符列.这些函数接受字符输入,返回字符或数字值.Oracle 提供的一些字符函数如 ...

  2. mybatis中oracle in>1000的处理

    oracle数据库中,如果你使用in,然后括号对应的是一个子查询,当查询出来的结果>1000的时候就会报错. 这个是数据库的规定,我们无法改变它. 如何解决这个问题呢? 现在我看到了三种解决方式 ...

  3. “java.sql.SQLException: Value '0000-00-00' can not be represented as java.sql.Timestamp”

    最近在项目中使用hibernate查询时,总报错“java.sql.SQLException: Value '0000-00-00' can not be represented as java.sq ...

  4. (转) mysql的连接,创建账号,修改密码

    原文:http://blog.chinaunix.net/uid-20749043-id-1878306.html  mysql的连接,创建账号,修改密码 2008-10-13 15:31:29 分类 ...

  5. 生成Apk遇到的问题

    conversion to dalvik format failed with error 1 android proguard keep Parameterized class

  6. 12-27cell常用的属性

    1.创建cell //    创建一个cell并且设置cell的风格 UITableViewCell *cell  = [[UITableViewCell alloc]initWithStyle:UI ...

  7. iOS开发:cocoapods的使用

    Cocoapods是OS X和iOS下的一个第三方类库管理工具,通过CocoaPods工具我们可以为项目添加各种依赖库,减少了我们手动引入库需要的各种配置,同时使用cocoapods可以方便的查找新的 ...

  8. 17、SQL基础整理(事务)

    事务 事务==流程控制 确保流程只能成功或者失败,若出现错误会自动回到原点 例: begin tran insert into student values('111','王五','男','1999- ...

  9. 找不到请求的 .Net Framework Data Provider。可能没有安装.

    学习中遇到的问题: 找不到请求的 .Net Framework Data Provider.可能没有安装. 找到的解决方法 解决方法: 安装Microsoft SQL Server Compact 4 ...

  10. LeetCode Bulls and Cows (简单题)

    题意: 给出两个数字,输出(1)有多少位是相同的(2)有多少位不在正确的位置上. 思路: 扫一遍,统计相同的,并且将两串中不同的数的出现次数分别统计起来,取小者之和就是第2个答案了. class So ...