题意:有一个岛上住着一些神和魔,并且已知神和魔的数量,现在已知神总是说真话,魔总是说假话,有 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. Android 移动缩放的ImageView

    今天介绍一下Android中怎么实现ImageView的缩放和移动,自定义TouchImageView. public class TouchImageView extends ImageView { ...

  2. 毕向东day23--java基础-网络总结

    传输层:TCP/UDP   UDP例如:qq聊天,录屏软件,桌面共享     TCP建立链接:三次握手,例如,我叫你一声老王(一次),老王回答说:到.(二次),我对老王说,我知道你到了.(三次握手)! ...

  3. 给宏基装WIN8.1系统之问题与解决方法(原创)

    1.采用老毛桃U盘PE进入笔记本: 2.备份桌面文件以防丢失: 3.将下载好的Win8操作系统镜像加载到虚拟光驱,最好把操作系统拷贝到笔记本硬盘上,不然可能会出现意想不到的错误: 4.打开老毛桃桌面安 ...

  4. php中数据库的操作

    1.Mysql客户端介绍,命令行:这种方法不友好. 2.Mysql客户端介绍,Web形式的可视化界面(phpMyAdmin) 优点:只要有浏览器就可以操作数据库 缺点: a)创建数据库

  5. 利用WPF绘图

    C#入门经典 25章的一个例子,利用WPF绘图. XAML: <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/p ...

  6. Selenium - IWebDriver 控制scroll bar到底部

    有时候我们需要控制页面滚动条上的滚动条,但滚动条并非页面上的元素,这个时候就需要借助js是来进行操作.一般用到操作滚动条的会两个场景: 注册时的法律条文需要阅读,判断用户是否阅读的标准是:滚动条是否拉 ...

  7. 解决CSS小于12px的文字在谷歌浏览器显示问题

    做前端设计的人经常要接触CSS方面的问题,估计有不少人会遇到Chrome谷歌浏览器中CSS设置字体小于12px显示不正常,强创网络在做magento模板过程中就遇到了,起初以为是自己写的CSS的问题, ...

  8. Inherits、CodeFile、CodeBehind的区别

    Inherits.CodeFile.CodeBehind 在 ASP.NET 中使用代码隐藏方法来设计Web 窗体,可使页代码能够更清晰地从 HTML 内容中分离到完全单独的文件中. 通常一个 @pa ...

  9. EditText 控件

    <EditText android:layout_width="fill_parent" android:layout_height="wrap_content&q ...

  10. C++的虚函数表

    这里的例子全部来自陈皓的C++ 虚函数表解析,经过修改的. 编译器:g++ (Ubuntu 4.9.2-10ubuntu13) 4.9.2 环境:ubuntu 15.04  64位系统(地址占8字节) ...