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

当输入字符串为“no”的时候,如果x为天使,则y为魔鬼;x为魔鬼的时候,y就是天使,所以当输入字符串为“no”的时候他们为异类。。这不就是种类并查集的

0 (同类) 1(异类)并查集嘛!

再接着想,通过并查集我们可以把它们分成两类,一种是和他们的根节点同类,一种不是同类。。这一点要注意了,所有的他们并不是一定是一个父节点,假如

(1  2)(3  4) 那他们就不在一棵树上。。

用完并查集我们就要用一个数组来记录他们根节点的数目,而且还要记录每一个根节点与其同类和异类的两种情况的数目,然后我们只要用这些数可以组合出来

天使或魔鬼的数目就可以了,但是要保证只有一种方法可以,如果有好几种方法,那就无法确定。。还要注意的是当去组成天使或魔鬼的数目的时候,一个根节点只能选根节点的同类或异类来往上加,不能都选。。。

上一点是不是有点像01背包,用一些数来组成一个数,看有几种方法

最后就是输出路径(路径方法我之前写过,你也可以在网上搜一下)

接着就上代码吧!

 //https://www.cnblogs.com/geloutingyu/p/6142473.html    我是看这个网址才懂得,可以看一下
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
int v[],w[],n,a,b,gg[],jj[][],tag[][],dp[][],cc[][];
struct shudui
{
int start,last;
char q;
}m[];
int finds(int x)
{
if(x!=v[x])
{
int y=finds(v[x]);
w[x]=(w[x]+w[v[x]])%;
v[x]=y;
return y;
}
return x;
}
void join(int x,int y,int z)
{
int fx=finds(x);
int fy=finds(y);
if(fx==fy)
{
return;
}
else
{
v[fx]=fy;
w[fx]=(-w[x]+z-+w[y])%;
}
}
int main()
{
while(~scanf("%d%d%d",&n,&a,&b))
{
memset(w,,sizeof(w));
if(n+a+b==) break;
for(int i=;i<=a+b;++i)
{
v[i]=i;
}
while(n--)
{
char q[];
int x,y;
scanf("%d%d%s",&x,&y,q);
if(x==y)
continue;
if(strcmp("no",q)==)
{
join(x,y,);
}
else join(x,y,);
}
//int w1[1005],w2[1005];
memset(gg,,sizeof(gg)); //存根节点
memset(jj,,sizeof(jj));
memset(tag,,sizeof(tag)); //来记录根节点同来和异类的数目
memset(dp,,sizeof(dp)); //背包dp,看看有几种方法
memset(cc,,sizeof(cc)); //标记,做最后输出
int cnt=;
for(int i=;i<=a+b;++i) //统计集合个数
{
if(finds(i)==i)
{
gg[i]=++cnt;
}
}
for(int i=;i<=a+b;++i)
{
tag[gg[finds(i)]][w[i]]++;
}
dp[][]=;
for(int i=;i<=cnt;++i)
{
for(int j=;j<=a;++j)//dp[i][j]表示到第i个集合,人数达到j的方法数
{
if(j-tag[i][]>= && dp[i-][j-tag[i][]])
{
dp[i][j]+=dp[i-][j-tag[i][]];
jj[i][j]=tag[i][]; //jj是记录路径的
}
if(j-tag[i][]>= && dp[i-][j-tag[i][]])
{
dp[i][j]+=dp[i-][j-tag[i][]];
jj[i][j]=tag[i][];
}
}
}
if(dp[cnt][a]!=)
{
printf("no\n");
}
else
{
for(int i=cnt,j=a;j> && i>; i--)
{
if(jj[i][j]==tag[i][])
cc[i][]=;
else cc[i][]=;
j-=jj[i][j];
}
for(int i=;i<=a+b;++i)
{
if(cc[gg[finds(i)]][w[i]]) printf("%d\n",i);
}
printf("end\n");
}
}
return ;
}

C - BLG POJ - 1417 种类并查集加dp(背包)的更多相关文章

  1. Poj(1182),种类并查集

    题目链接:http://poj.org/problem?id=1182 再次熟练种类并查集,又积累点经验,和技巧,rank 0 2 1 先计算father[x] ,再更新rank[x]; #inclu ...

  2. Poj(1703),种类并查集

    题目链接:http://poj.org/problem?id=1703 已经不是第一次接触种类并查集了,直到今天才搞懂. 感谢红黑联盟,感谢杰哥!!! 每个节点只要关系确定,不管是不是同一个集合里面, ...

  3. POJ - 2492 种类并查集

    思路:保存每个点与其父节点的关系,注意合并和路径压缩即可. AC代码 #include <cstdio> #include <cmath> #include <cctyp ...

  4. poj 1182:食物链(种类并查集,食物链问题)

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 44168   Accepted: 12878 Description ...

  5. POJ 1733 Parity game(种类并查集)

    http://poj.org/problem?id=1733 题意: 给出一个01串,有多次询问,每次回答[l,r]这个区间内1的个数的奇偶性,但是其中有一些回答是错误的,问到第几个回答时与前面的回答 ...

  6. 种类并查集,Poj(1703)

    题目链接:http://poj.org/problem?id=1703 第一次做种类并查集,有的地方还不是很清楚,想了一上午,有点明白了,这里记录一下. 这里我参考的红黑联盟的题解. 关键:种类并查集 ...

  7. poj 1182 食物链(种类并查集 ‘初心者’)

    题目链接:http://poj.org/problem?id=1182 借着这题可以好好理解一下种类并查集,这题比较简单但挺经典的. 题意就不解释了,中问题. 关于种类并查集结局方法也是挺多的 1扩增 ...

  8. 【POJ】2492 A bug's life ——种类并查集

    A Bug's Life Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 28211   Accepted: 9177 De ...

  9. poj 2492 A Bug's Life 二分图染色 || 种类并查集

    题目链接 题意 有一种\(bug\),所有的交往只在异性间发生.现给出所有的交往列表,问是否有可疑的\(bug\)(进行同性交往). 思路 法一:种类并查集 参考:https://www.2cto.c ...

随机推荐

  1. Java8新特性(一)_interface中的static方法和default方法

    什么要单独写个Java8新特性,一个原因是我目前所在的公司用的是jdk8,并且框架中用了大量的Java8的新特性,如上篇文章写到的stream方法进行过滤map集合.stream方法就是接口Colle ...

  2. js 实现数据结构 -- 字典

    原文: 在Javascript 中学习数据结构与算法. 概念: 集合.字典.散列表都可以存储不重复的数据.字典和我们上面实现的集合很像. 当然,字典中的数据具有不重复的特性.js 中 Object 的 ...

  3. Spring MVC 使用介绍(十二)控制器返回结果统一处理

    一.概述 在为前端提供http接口时,通常返回的数据需要统一的json格式,如包含错误码和错误信息等字段. 该功能的实现有四种可能的方式: AOP 利用环绕通知,对包含@RequestMapping注 ...

  4. sql 查询字段如果为null 则返回0的写法

    oracle select nvl(字段名,0) from 表名; ----------------------------------- sqlserver select isnull(字段名,0) ...

  5. django rest framework serializers

    django rest framework serializers序列化   serializers是将复杂的数据结构变成json或者xml这个格式的 serializers有以下几个作用:- 将qu ...

  6. 一道php笔试题

    原文地址: http://www.walu.cc/php/a-bishiti.md 问题: 请找出下面代码中的问题,修复并优化. <?php //批量注册用户,每次>100个. //注册新 ...

  7. JavaScript自动生成博文目录导航/TOP按钮

    博客园页面添加返回顶部TOP按钮 进入网页管理->设置 在"页面定制CSS代码"中添加如下css样式,当然你可以改为自己喜欢的样式 此处可以将背景色background-co ...

  8. Excel中最精确的计算年龄的公式

    身份证算年龄 假设A1是身份证号所在单元格 =IF(MONTH(NOW())<INT(MID(A1,11,2)),INT(YEAR(NOW())-INT(MID(A1,7,4)))-1,IF(M ...

  9. Python的安装与小程序的编写

    Python的安装 在此之前,我完全不了解Python,为了完成任务,在慌忙之中了解了一下Python,通过百度,一步步安装好Python 过程 1.从官网中找到下载菜单并下载最新版本 2.双击pyt ...

  10. Windows10搭建FTP服务

    1.启用Windows10 Ftp服务 打开控制面板->程序和功能->启用或关闭windows功能然后如图: 2.配置FTP用户 我的电脑->右击点击管理->本地用户和组 在A ...