POJ 1417 True Liars(路径压缩并查集+DP背包问题)
POJ 1417 True Liars(路径压缩并查集+DP背包问题)
http://poj.org/problem?id=1417
题意:
给出p1+p2个人,其中p1个是好人,p2个是坏人。然后有一些关系 ,a说b是好人(坏人).其中没有矛盾的,判断是否有唯一解判断哪些人是好人,哪些人是坏人。
其中比较重要的是,好人总说真话,坏人总说假话(这句话的特殊意义)。不会存在矛盾情况。请问你是否存在唯一解,如果存在请输出唯一解。
分析:
如果A说B是好人,那么A与B是同一类人。如果A说B是坏人,那么A与B不同类。(想想为什么是这样)
所以原题所给的每句话就是一条路径压缩并查集的关系,那么我们最终合并所有关系可以得到cnt个连通分量且每个分量中节点的相互关系(同类or异类)我们都知道。
好,现在假设有cnt个连通分量,第一个分量有x1与y1个两类人(我们不知道到底x1那些人是好人还是y1那些人是好人),第二个分量有x2与y2个两类人...所以我们现在想知道是否只有一种方式让我们从第一分量中抓X1(或Y1)个人来,从第二分量中抓X2(或Y2)人来...直到每个分量都抓一类人时,正好抓了p1个人。
如果只有1种方式实现上面的目的,那么就有唯一解。记录DP的每次选择最后输出即可。
令d[i][j]表示取完前i个分量后正好j人的方法数,我们最后要求的是看d[cnt][p1]是否==1?
DP转移方程:dp[i][j]=sum{ dp[i-1][j-bag[i][0]]+dp[i-1][j-bag[i][1]] }
AC代码:
<span style="font-size:18px;">#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
const int MAXN=1000;
int bag[MAXN][2];//bag[i][0]表示第i(重新编号了)个连通分量的0类人的个数,bag[i][1]表1类人
map<int,int> mp;//用来将老的连通分量编号映射bag中的新编号
int cnt;//一共有cnt个分量
int insert(int x,int b)//连通分量x,与x的关系是b(0表示同类,1表示异类)
{if(mp.find(x)==mp.end())mp[x]=++cnt;bag[mp[x]][b]++;//该分量的b类人加1return mp[x];
}
int F[MAXN];
int v[MAXN];//表示i与根的关系
int findset(int i)
{if(F[i]==-1)return i;int temp= findset(F[i]);v[i] =(v[i]+v[F[i]])%2;return F[i]=temp;
}
void bind(int i,int j,int temp)
{int fa=findset(i);int fb=findset(j);if(fa!=fb){F[fb]=fa;v[fb]=(v[i]+v[j]+temp)%2;}
}
int d[MAXN][310];//DP
int main()
{int n,p1,p2;while(scanf("%d%d%d",&n,&p1,&p2)==3){if(n==0&&p1==0&&p2==0)break;cnt=0;mp.clear();memset(bag,0,sizeof(bag));memset(F,-1,sizeof(F));memset(v,0,sizeof(v));memset(d,0,sizeof(d));while(n--){int a,b,temp;char str[10];scanf("%d%d%s",&a,&b,str);if(str[0]=='y')temp=0;else if(str[0]=='n')temp=1;int fa=findset(a);int fb=findset(b);if(fa!=fb)//不同分量bind(a,b,temp);;}for(int i=1;i<=p1+p2;i++)//将1到p1+p2所有点重新编号{int fi=findset(i);insert(fi,v[i]);}d[0][0]=1;//初值for(int i=1;i<=cnt;i++)//连通分量编号从1到cnt{for(int j=0;j<=p1;j++){if( j>=bag[i][0] )d[i][j] = d[i-1][j-bag[i][0]];if( j>=bag[i][1] )d[i][j] += d[i-1][ j-bag[i][1] ];}}//printf("###%d\n",d[cnt][p1]);if(d[cnt][p1]==1)//能区分出{int j=p1;int choose[MAXN];//choose[i]=1/0表示第i(重新编号)个连通分量选择第0类还是选第1类memset(choose,-1,sizeof(choose));for(int k=cnt;k>=1;k--)//逆推找出choose{if( d[k][j] == d[k-1][j-bag[k][0]] ){choose[k]=0;j=j-bag[k][0];}else if( d[k][j] == d[k-1][j-bag[k][1]] ){choose[k]=1;j=j-bag[k][1];}}for(int i=1;i<=p1+p2;i++){int fa=findset(i);//找出分量的编号faint num=mp[fa];//找出fa重新编号后的编号 numif(v[i]==choose[num])printf("%d\n",i);}printf("end\n");}else{printf("no\n");}}return 0;
}
</span>
POJ 1417 True Liars(路径压缩并查集+DP背包问题)相关推荐
- POJ 1417 True Liars(带权并查集+DP)
传送门 Description After having drifted about in a small boat for a couple of days, Akira Crusoe Maeda ...
- POJ 1417 True Liars 带权并查集 + 背包
一.内容 After having drifted about in a small boat for a couple of days, Akira Crusoe Maeda was finally ...
- POJ 1703 Find them, Catch them(路径压缩并查集)
POJ 1703 Find them, Catch them(路径压缩并查集) 2014年03月11日 20:13:54 阅读数:881 POJ 1703 Find them, Catch them( ...
- POJ 1417 True Liars 并查集+背包
题目链接:http://poj.org/problem?id=1417 解题思路:比较容易想到的是并查集,然后把第三组数据测试一下之后发现这并不是简单的并查集,而是需要合并之后然后判断的.并且鉴于题目 ...
- POJ 1417 True Liars (种类并查集+DP)
题目:True Liars 题目大意:给出n对关系,p1个好人,p2个坏人.要求根据n对关系中找出好人有哪些,若方案唯一,则逐个输出好人,最后输出end:若方案不唯一/找不到,那么输出no 结论:通过 ...
- POJ - 1417 True Liars POJ - 141 带权并查集,01背包问题
题目链接 POJ-1417 题意 岛上有说真话的好人和说假话的坏人,给你这两种人的人数.再给出q次问答结果,问答的格式是向a询问b是否是好人,回答是yes或者no.问是否可以分辨出全部好人,是的话打印 ...
- [POJ 1417] True Liars
[题目链接] http://poj.org/problem?id=1417 [算法] 首先,我们发现 : 如果A说B是好人,那么A和B是同一类人,否则A和B不是同一类人 利用这个 ...
- POJ - 1417(True Liars)
题意:雾岛上有两个部落,天使部落有 p1 个人,他们只说真话,恶魔部落有 p2 个人,他们只说假话,但是两个部落的人长得一模一样,把这 p1+p2 个人从1编号,然后有 n 次询问,每次询问给出 a ...
- POJ 1703 Find them, Catch them(并查集高级应用)
POJ 1703 Find them, Catch them(并查集高级应用) 手动博客搬家:本文发表于20170805 21:25:49, 原地址https://blog.csdn.net/sunc ...
最新文章
- Google开源项目风格指南-笔记
- JdbcTmplate中的update方法(代码)基础操作
- bootstrap 起步
- 【android】og
- Android二维码之创建
- 中文巨量模型“源1.0”:模型结构与生成效果解析
- 互联网日报 | 7月15日 星期四 | B站赠送所有用户1天大会员;饿了么投入3亿用于今夏骑手保障;小米智能工厂二期开工...
- python数据结构之 set
- Linux进程实践(3) --进程终止与exec函数族
- PiFlow大数据流水线系统v0.9源码
- 【C语言】逗号运算符的使用举例
- 获取分割字符串的内容高级技巧
- 获取本地视频url的方法
- 【工具推荐】在线latex公式编辑器(可用鼠标交互)
- 投入产出与投入占用产出技术在经济分析中的应用(指标计算和投入产出分析)...
- http://www.cnblogs.com/dolphin0520/p/3923167.html
- Python绘制某图片(LOL)
- 兄弟1218无线打印服务器错误,兄弟hl-1218w打印机无线连接方法_兄弟hl-1218w打印机无线怎么连接-硬件之家...
- 智能型手机中的音频设计方案
- 关于intellij idea的