poj1417 带权并查集+0/1背包
题意:有一个岛上住着一些神和魔,并且已知神和魔的数量,现在已知神总是说真话,魔总是说假话,有 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背包的更多相关文章
- poj1417 带权并查集 + 背包 + 记录路径
True Liars Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2713 Accepted: 868 Descrip ...
- poj1417(带权并查集+背包DP+路径回溯)
题目链接:http://poj.org/problem;jsessionid=8C1721AF1C7E94E125535692CDB6216C?id=1417 题意:有p1个天使,p2个恶魔,天使只说 ...
- POJ 1703 Find them, Catch them(带权并查集)
传送门 Find them, Catch them Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 42463 Accep ...
- [NOIP摸你赛]Hzwer的陨石(带权并查集)
题目描述: 经过不懈的努力,Hzwer召唤了很多陨石.已知Hzwer的地图上共有n个区域,且一开始的时候第i个陨石掉在了第i个区域.有电力喷射背包的ndsf很自豪,他认为搬陨石很容易,所以他将一些区域 ...
- poj1984 带权并查集(向量处理)
Navigation Nightmare Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 5939 Accepted: 2 ...
- 【BZOJ-4690】Never Wait For Weights 带权并查集
4690: Never Wait for Weights Time Limit: 15 Sec Memory Limit: 256 MBSubmit: 88 Solved: 41[Submit][ ...
- 洛谷OJ P1196 银河英雄传说(带权并查集)
题目描述 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦 创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山 ...
- poj1611 带权并查集
题意:病毒蔓延,现在有 n 个人,其中 0 号被认为可能感染,然后给出多个社交圈,如果某个社交圈里有人被认为可能被感染,那么所有这个社交圈里的人都被认为可能被感染,现在问有多少人可能被感染. 带权并查 ...
- hdu 1829-A Bug's LIfe(简单带权并查集)
题意:Bug有两种性别,异性之间才交往, 让你根据数据判断是否存在同性恋,输入有 t 组数据,每组数据给出bug数量n, 和关系数m, 以下m行给出相交往的一对Bug编号 a, b.只需要判断有没有, ...
随机推荐
- asp.net页面使用doPostBack的后台取值
前台页面(aspx文件): --伪装按钮 <span onclick='__doPostBack("lkSend","key")'>发送</s ...
- poj2264 dp+路径
//Accepted 208K 0MS //dp //最长公共子序列+路径 #include <cstdio> #include <cstring> #include < ...
- acm 20140825
为了自己的梦想,一次次的选择坚强.走上acm这条路,怎么也找不到让自己放弃的理由.我喜欢这种竞赛的氛围,我渴望在赛场上飞扬!想想过去的一个学习,自己并没有干点什么有意义的事.acm也没有好好的做!新的 ...
- Canopy测试IPython控制台输出
Canopy测试IPython控制台输出
- Design Patterns
经典的<设计模式>一书归纳出23种设计模式,本文按<易学设计模式>一书归纳分类如下:1.创建型模式 前面讲过,社会化的分工越来越细,自然在软件设计方面也是如此,因此对象的创建和 ...
- C/C++ static vs global
static has a very simple logic to it. If a variable is static, it means that it is a global variable ...
- 在MyEclipse上搭建web服务器
a) Servlet是什么? Servlet(服务器端小程序)是使用Java语言编写的服务器端程序[o1] ,可以使用脚本语言,生成动态的web页. b) Servlet的架构? ...
- Java容器类接口的选择
我们知道Java容器类实际提供了四类接口:Map,List,Set和Queue,如下图所示,每种接口都有不止一个版本的实现,如果在实际编写程序时需要使用某种接口时该如何选择. 从Oracle的Java ...
- 深入分析:Android中app之间的交互(一,使用Action)
在我们开发Android App应用的时候,有些需求需要我们启动其他的App来处理一些逻辑,例如我们需要根据一个地址来调用系统或者相关的地图Map App,这样我们不用在自己的App中编写相应的功能, ...
- Squid代理之普通代理
1.配置Squid 代理服务器IP地址 将eth1的IP地址修改为200.168.10.1