题目链接

POJ-1417

题意

岛上有说真话的好人和说假话的坏人,给你这两种人的人数。再给出q次问答结果,问答的格式是向a询问b是否是好人,回答是yes或者no。问是否可以分辨出全部好人,是的话打印清单

思路

这一篇是带权并查集解法,如果想看拓展并查集解法请戳这里。

首先处理关系部分需要用到带权并查集,初次接触带权并查集的话请戳这里,按照那篇题解中的思路来看这篇题解~。我们将value设置为与父节点关系,0代表同类,1代表不同。那么初始化va数组为0,在find函数按轶合并部分我们用^ 异或上父节点value更新(具体可以手推一下),在unite部分如果ab同类,合并后的value就是va[a] ^ va[b] ^ 0,不同就是va[a] ^ va[b] ^ 1。(怎么来的可以按我贴的连接画图推一下,或者参考别的讲解带权并查集的博客)。

第一步完成后,我们拥有了并查集管理的多个独立块,在每一个集合中,权值为0的和权值为1的可以划分成两个子集合,我们的任务就是从每一个集合中选取一个子集,最终让这些子集元素数和为好人人数,且这样的选择唯一,那么用01背包跑一下就可以了。

代码

#include<iostream>
#include<vector>
#include<cstring>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl "\n"
using namespace std;typedef long long ll;const int maxn=2050;const int inf=0x3f3f3f3f;int fa[maxn];//父节点 int va[maxn];int q,n,m;int dp[1050][1050];//dp数组 bool ans[1050];//打印答案 bool b[1050];//集合去重 vector<int>v[maxn]; //暂时记录不同集合包含的点 vector<int>v1[maxn];//v1v2存放每个集合的子集 vector<int>v2[maxn];//void init(){for(int i=0;i<maxn;i++){fa[i]=i;va[i]=0;}memset(dp,0,sizeof(dp));memset(b,0,sizeof(b));memset(ans,0,sizeof(ans));for(int i=0;i<maxn;i++){v[i].clear();v1[i].clear();v2[i].clear();}}int find(int x){if(fa[x]==x)return x;int t=find(fa[x]);va[x]^=va[fa[x]]; return fa[x]=t;}void unite(int x,int y,int t){int xr=find(x),yr=find(y);if(xr==yr){return ;}fa[xr]=yr;va[xr]=va[x]^va[y]^t;}int main(){IOSwhile(cin>>q>>n>>m){if(!q&&!n&&!m)break;init();int sm=n+m;while(q--){int a,b;string s;cin>>a>>b>>s;if(s=="yes"){unite(a,b,0);}else{unite(a,b,1);}}if(n==m){cout<<"no"<<endl;continue;}for(int i=1;i<=sm;i++){int x=find(i);v[x].push_back(i);}int t=1;for(int i=1;i<=2*sm;i++){bool bl=0;int le=v[i].size();for(int j=0;j<le;j++){int tmp=v[i][j];if(va[tmp]==0){v1[t].push_back(tmp);bl=1;}else{v2[t].push_back(tmp);bl=1;}}if(bl)t++;}//dp部分 dp[0][0]=1;for(int i=1;i<t;i++){int s1=v1[i].size(),s2=v2[i].size();for(int j=n;j>=s1;j--)dp[i][j]+=dp[i-1][j-s1];for(int j=n;j>=s2;j--)dp[i][j]+=dp[i-1][j-s2];}if(dp[t-1][n]!=1)cout<<"no"<<endl;else{int tmp=n;for(int i=t-1;i>=1;i--){int s1=v1[i].size(),s2=v2[i].size();if(dp[i-1][tmp-s1]==1){for(int j=0;j<s1;j++){//cout<<v1[i][j]<<endl;ans[v1[i][j]]=1;}tmp-=s1;}else{for(int j=0;j<s2;j++){//cout<<v1[i][j]<<endl;ans[v2[i][j]]=1;}tmp-=s2;}}for(int i=1;i<=sm;i++){if(!ans[i])continue;cout<<i<<endl;}cout<<"end"<<endl;}}return 0;}

POJ - 1417 True Liars POJ - 141 带权并查集,01背包问题相关推荐

  1. POJ 1984 Navigation Nightmare 【经典带权并查集】

    任意门:http://poj.org/problem?id=1984 Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K To ...

  2. POJ 2492 A Bug's Life 带权并查集

    题意: 思路: mod2 意义下的带权并查集 如果两只虫子是异性恋,它们的距离应该是1. 如果两只虫子相恋且距离为零,则它们是同性恋. (出题人好猥琐啊) 注意: 不能输入一半就break出来.... ...

  3. POJ 2492 A Bug's Life (带权并查集 向量偏移)

    题意 : 给你 n 只虫且性别只有公母, 接下来给出 m 个关系, 这 m 个关系中都是代表这两只虫能够交配, 就是默认异性, 问你在给出的关系中有没有与异性交配这一事实相反的, 即同性之间给出了交配 ...

  4. poj 1182 食物链(高级的带权并查集)

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

  5. POJ 1417 True Liars 并查集+背包

    题目链接:http://poj.org/problem?id=1417 解题思路:比较容易想到的是并查集,然后把第三组数据测试一下之后发现这并不是简单的并查集,而是需要合并之后然后判断的.并且鉴于题目 ...

  6. POJ 1417 True Liars(路径压缩并查集+DP背包问题)

    POJ 1417 True Liars(路径压缩并查集+DP背包问题) http://poj.org/problem?id=1417 题意: 给出p1+p2个人,其中p1个是好人,p2个是坏人.然后有 ...

  7. 【POJ - 1703】Find them, Catch them(带权并查集之--种类并查集 权为与父节点关系)

    题干: Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 36176   Accep ...

  8. POJ 1182 食物链 [并查集 带权并查集 开拓思路]

    传送门 P - 食物链 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit  ...

  9. POJ 2912 Rochambeau(难,好题,枚举+带权并查集)

    下面的是从该网站上copy过来的,稍微改了一点,给出链接:http://hi.baidu.com/nondes/item/26dd0f1a02b1e0ef5f53b1c7 题意:有N个人玩剪刀石头布, ...

最新文章

  1. js获取网页当前页面及路径
  2. Flagger on ASM——基于Mixerless Telemetry实现渐进式灰度发布系列 2 应用级扩缩容
  3. 题目1023:EXCEL排序---------Case后面的是count,不是C
  4. Java EE中的配置管理
  5. jquery 读取checkbox
  6. ssm mysql 例子_ssm入门级示例(mysql数据库)
  7. 火星开发的价值_发现“火星”岩石密度比预想更低,火星探测开发的“九大价值”...
  8. aes简单文本加密工具
  9. Dell电脑重装系统
  10. U盘被写保护或无法写数据无法格式化的问题解决
  11. EcmaScript 2022中的新特性
  12. SpringBoot + vue 解决跨域问题
  13. 神经网络中的filter(滤波器)和kernel(内核)的概念
  14. 疫情过后,制造业中小企业应用工业互联网数字化转型之路的探讨
  15. foxmail远程主机强迫关闭了一个现有的连接
  16. 关于网线水晶头的接法详解(2)
  17. 三级指标 主成分分析_(完整版)主成分分析法的步骤和原理
  18. NGFF、M.2、NVME、SATA、PCIE、USB的层次和区别:协议?接口?
  19. 【微信小程序提取公共请求数据】
  20. linux 文件切割

热门文章

  1. 出其不意小妙招(持续更新中)
  2. C++控制台程序判断输入的数字
  3. 第 27、28、29 节 接口、抽象类、SOLID、单元测试、反射
  4. 总结关于找工作的20条经验
  5. 我是如何逃离“毕业即失业”魔咒的?初学Python为啥突然爆红?
  6. Linux文件内容排序命令sort
  7. css用浮动的方法让div在同一行
  8. windows上的cuda8和cuda9切换,win10 + vs2015
  9. YOLOv6 Pro | YOLOv6网络魔改 (1) ——RepGFPN融合高效聚合网络(ELAN)和重参数化的目标检测Neck(来自DAMO-YOLO)
  10. 阿里云发布行业首个「视频直播技术最佳实践图」!