poj1417 带权并查集 + 背包 + 记录路径
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 2713 | Accepted: 868 |
Description
In order to prevent the worst-case scenario, Akira should distinguish the devilish from the divine. But how? They looked exactly alike and he could not distinguish one from the other solely by their appearances. He still had his last hope, however. The members of the divine tribe are truth-tellers, that is, they always tell the truth and those of the devilish tribe are liars, that is, they always tell a lie.
He asked some of them whether or not some are divine. They knew one another very much and always responded to him "faithfully" according to their individual natures (i.e., they always tell the truth or always a lie). He did not dare to ask any other forms of questions, since the legend says that a devilish member would curse a person forever when he did not like the question. He had another piece of useful informationf the legend tells the populations of both tribes. These numbers in the legend are trustworthy since everyone living on this island is immortal and none have ever been born at least these millennia.
You are a good computer programmer and so requested to help Akira by writing a program that classifies the inhabitants according to their answers to his inquiries.
Input
n p1 p2
xl yl a1
x2 y2 a2
...
xi yi ai
...
xn yn an
The first line has three non-negative integers n, p1, and p2. n is the number of questions Akira asked. pl and p2 are the populations of the divine and devilish tribes, respectively, in the legend. Each of the following n lines has two integers xi, yi and one word ai. xi and yi are the identification numbers of inhabitants, each of which is between 1 and p1 + p2, inclusive. ai is either yes, if the inhabitant xi said that the inhabitant yi was a member of the divine tribe, or no, otherwise. Note that xi and yi can be the same number since "are you a member of the divine tribe?" is a valid question. Note also that two lines may have the same x's and y's since Akira was very upset and might have asked the same question to the same one more than once.
You may assume that n is less than 1000 and that p1 and p2 are less than 300. A line with three zeros, i.e., 0 0 0, represents the end of the input. You can assume that each data set is consistent and no contradictory answers are included.
Output
Sample Input
2 1 1
1 2 no
2 1 no
3 2 1
1 1 yes
2 2 yes
3 3 yes
2 2 1
1 2 yes
2 3 no
5 4 3
1 2 yes
1 3 no
4 5 yes
5 6 yes
6 7 no
0 0 0
Sample Output
no
1
2
end
3
4
5
6
end
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<string>
#include<time.h>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 1000000001
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int MAXN = ;
int pa[MAXN],n,p1,p2,rel[MAXN],vis[MAXN];
vector<int>b[MAXN][];
int a[MAXN][],dp[MAXN][MAXN],pre[MAXN][MAXN];
void Init()
{
for(int i = ; i <= p1 + p2; i++){
pa[i] = i;
b[i][].clear();
b[i][].clear();
a[i][] = ;
a[i][] = ;
}
memset(rel,,sizeof(rel));
}
int find(int x)
{
if(x != pa[x]){
int fx = find(pa[x]);
rel[x] = (rel[x] + rel[pa[x]]) % ;
pa[x] = fx;
}
return pa[x];
}
int main()
{
while(~scanf("%d%d%d",&n,&p1,&p2)){
if(!n && !p1 && !p2)break;
Init();
int x,y,z;
char s[];
for(int i = ; i < n; i++){
scanf("%d %d %s",&x,&y,s);
if(s[] == 'y'){
z = ;
}
else {
z = ;
}
int fx = find(x);
int fy = find(y);
if(fx != fy){
pa[fx] = fy;
rel[fx] = ( - rel[x] + z + rel[y]) % ;
}
}
memset(vis,,sizeof(vis));
int cnt = ;
for(int i = ; i <= p1 + p2; i++){
if(!vis[i]){
int tp = find(i);
for(int j = i; j <= p1 + p2; j++){
int fp = find(j);
if(fp == tp){
vis[j] = ;
b[cnt][rel[j]].push_back(j);
a[cnt][rel[j]] ++;
}
}
//cout<<a[cnt][0]<<' '<<a[cnt][1]<<endl;
cnt ++;
}
}
memset(vis,,sizeof(vis));
memset(dp,,sizeof(dp));
dp[][] = ;
for(int i = ; i < cnt; i++){
for(int j = p1; j >= ; j--){
if(j - a[i][] >= && dp[i-][j - a[i][]]){
dp[i][j] += dp[i-][j-a[i][]];
pre[i][j] = j - a[i][];
}
if(j - a[i][] >= && dp[i-][j - a[i][]]){
dp[i][j] += dp[i-][j-a[i][]];
pre[i][j] = j - a[i][];
}
}
}
if(dp[cnt-][p1] != ){
printf("no\n");
}
else {
vector<int>ans;
int l = p1;
for(int i = cnt - ; i >= ; i--){
int tp = l - pre[i][l];
if(tp == a[i][]){
for(int j = ; j < b[i][].size(); j++){
ans.push_back(b[i][][j]);
}
}
else {
for(int j = ; j < b[i][].size(); j++){
ans.push_back(b[i][][j]);
}
}
l = pre[i][l];
}
sort(ans.begin(),ans.end());
for(int i = ; i < ans.size(); i++){
printf("%d\n",ans[i]);
}
printf("end\n");
}
}
return ;
}
poj1417 带权并查集 + 背包 + 记录路径的更多相关文章
- poj1417(带权并查集+背包DP+路径回溯)
题目链接:http://poj.org/problem;jsessionid=8C1721AF1C7E94E125535692CDB6216C?id=1417 题意:有p1个天使,p2个恶魔,天使只说 ...
- poj1417 带权并查集+0/1背包
题意:有一个岛上住着一些神和魔,并且已知神和魔的数量,现在已知神总是说真话,魔总是说假话,有 n 个询问,问某个神或魔(身份未知),问题是问某个是神还是魔,根据他们的回答,问是否能够确定哪些是神哪些是 ...
- 西安邀请赛-D(带权并查集+背包)
题目链接:https://nanti.jisuanke.com/t/39271 题意:给定n个物品,m组限制,每个物品有个伤害值,现在让两个人取完所有物品,要使得两个人取得物品伤害值之和最接近,输出伤 ...
- 洛谷P1196 [NOI2002]银河英雄传说(带权并查集)
题目描述 公元五八○一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山压顶 ...
- 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很自豪,他认为搬陨石很容易,所以他将一些区域 ...
- 【BZOJ-4690】Never Wait For Weights 带权并查集
4690: Never Wait for Weights Time Limit: 15 Sec Memory Limit: 256 MBSubmit: 88 Solved: 41[Submit][ ...
- hdu 1829-A Bug's LIfe(简单带权并查集)
题意:Bug有两种性别,异性之间才交往, 让你根据数据判断是否存在同性恋,输入有 t 组数据,每组数据给出bug数量n, 和关系数m, 以下m行给出相交往的一对Bug编号 a, b.只需要判断有没有, ...
- POJ 2912 Rochambeau(难,好题,枚举+带权并查集)
下面的是从该网站上copy过来的,稍微改了一点,给出链接:http://hi.baidu.com/nondes/item/26dd0f1a02b1e0ef5f53b1c7 题意:有N个人玩剪刀石头布, ...
随机推荐
- html5的小知识点小集合
html5的小知识点小集合 html5知识 1. Doctype作用?标准模式与兼容模式各有什么区别? (1).<!DOCTYPE>声明位于位于HTML文档中的第一行,处于< ...
- Android驱动入门-LED--HAL硬件访问服务层②
硬件平台: FriendlyARM Tiny4412 Cortex-A9 操作系统: UBUNTU 14.04 LTS 时间:2016-09-21 16:58:56 为了避免访问冲突,则创建了硬件访 ...
- [No000005]C#注册表操作,创建,删除,修改,判断节点是否存在
//用.NET下托管语言C#操作注册表,主要内容包括:注册表项的创建,打开与删除.键值的创建(设置值.修改),读取和删除.判断注册表项是否存在.判断键值是否存在. //准备工作: //1:要操作注册表 ...
- HTML 学习笔记 JavaScript(简介)
JavaScript 是世界上最流行的编程语言. 这门语言可用于HTML和web 更可广泛用于服务器.PC.笔记本电脑.平板电脑和智能手机等设备. JavaScript是脚本语言 JavaScript ...
- SQL探险
两张表,取相同字段比较 相同则显示true 否则FALSE.
- C# 根据正则表达式来判断输入的是不是数字
最近在做输入判断的时候出现了一个需要判断输入合法性的问题,就是判断输入的是不是数字,判断方法是根据正则表达式来判断,具体方法如下: private bool IsRightNum(string str ...
- SharePoint 2010自定义母版页小技巧——JavaScript和CSS引用
通常在我们的项目中,都会涉及到母版页的定制.并且必不可少的,需要配合以一套自己的JavaScript框架和CSS样式.你有没有遇到过这样的情况呢,在开发环境和UAT时都还算顺利,但是当最终部署到生产服 ...
- [转]nodejs npm常用命令
FROM : http://www.cnblogs.com/linjiqin/p/3765772.html npm是一个node包管理和分发工具,已经成为了非官方的发布node模块(包)的标准.有了n ...
- How do I list the files in a directory?
原文地址:How do I list the files in a directory? You want a list of all the files, or all the files matc ...
- JDK动态代理和CGLib动态代理简单演示
JDK1.3之后,Java提供了动态代理的技术,允许开发者在运行期间创建接口的代理实例. 一.首先我们进行JDK动态代理的演示. 现在我们有一个简单的业务接口Saying,如下: package te ...