vijos1531 食物链
背景
安徽省芜湖市第二十七中学测试题
NOI 2001 食物链(eat)
Description:Official
Data:Official
Program:JackDavid127
描述
动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形。A吃B,B吃C,C吃A。
现有N个动物,以1-N编号。每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种。
有人用两种说法对这N个动物所构成的食物链关系进行描述:
第一种说法是“1 X Y”,表示X和Y是同类。
第二种说法是“2 X Y”,表示X吃Y。
此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。
1) 当前的话与前面的某些真的话冲突,就是假话;
2) 当前的话中X或Y比N大,就是假话;
3) 当前的话表示X吃X,就是假话。
你的任务是根据给定的N(1<=N<=50,000)和K句话(0<=K<=100,000),输出假话的总数。
格式
输入格式
第一行是两个整数N和K,以一个空格分隔。
以下K行每行是三个正整数D,X,Y,两数之间用一个空格隔开,其中 D 表示说法的种类。
若D=1,则表示X和Y是同类。
若D=2,则表示X吃Y。
输出格式
只有一个整数,表示假话的数目。
限制
1S
提示
并查集
对样例的解释
输入文件 对7句话的分析
100 7
1 101 1 假话
2 1 2 真话
2 2 3 真话
2 3 3 假话
1 1 3 假话
2 3 1 真话
1 5 5 真话
分析与解:最近刚刚做过一道叫“关押罪犯”的联赛题,偶然间又发现了这道题,仔细一想,发现这根本就是那道题做了一点点小变化而已,所以,没用多久很快就做出来了。看这道题,题目要求我们判假,如果我们用并查集来做这道题,应该何从下手呢?首先,很显然的是,我们必须维护一个点与点关系的集合,通过这个关系集合来判假。原始的并查集只能用于维护“属于同一类“的这种关系,但是这道题却还要求我们维护吃的关系,这样才能针对每一个给出的论断进行判断。维护属于同一组的这种信息很容易实现,但是又如何体现捕食的关系呢?稍加思考,可以这样来转化。针对每只动物,为他们分别创建三个元素,每个元素表示不同的种类信息(具体实现为i表示这只动物是A,i+N就表示是B,i+2*N就表示这只动物是C了),这样,就用N*3个元素来建立并查集,这样,种类信息便成功加进来了。再来,就是维护了。其实很简单,虽然不知道给出的每一个论断(这里指第二种)中,两只动物分别是什么种类的,但事实上无需知道,因为食物链是一个环,随便哪一点选作A都行,只要每种动物的相对关系不变就行。所以,我们把同一个集合中的所有元素都看做符合事实,由于加上了类型信息,所以吃的关系也能判断出来。如此一来,针对每一个论断直接判断是否矛盾,不矛盾,就更新集合,否则是假话,把计数变量加一就可以了。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = ;
int n,k;
int d,a,b;
int ans;
int fa[maxn];
inline int read(){
char ch=getchar();
int f=,x=;
while(!(ch>=''&&ch<='')){if(ch=='-')f=-;ch=getchar();};
while(ch>=''&&ch<=''){x=x*+(ch-'');ch=getchar();};
return x*f;
}
int findf(int x){
return x == fa[x] ? x : fa[x] = findf(fa[x]);
}
int un(int x,int y){
x = findf(x);
y = findf(y);
if(x != y) fa[x] = y;
}
bool same(int x,int y){
x = findf(x);
y = findf(y);
return x == y;
}
int main(){
n = read();
k = read();
int m = n*;
for(int i = ;i <= m;i++) fa[i] = i;
for(int i = ;i <= k;i++){
d = read();
a = read();
b = read();
if(a > n || b > n){
ans++;
continue;
}
if(a == b && d != ){
ans++;
continue;
}
if(d == ){
if(same(a,b+n) || same(a,b+*n)){
ans++;
continue;
}
un(a,b);
un(a+n,b+n);
un(a+n*,b+n*);
}
if(d == ){
if(same(a,b) || same(a,b+n*)){
ans++;
continue;
}
un(a,b+n);
un(a+n,b+n*);
un(a+n*,b);
}
}
cout<<ans;
return ;
}
特别注意补集思想的运用,注意吃与被吃构成环,不需要像关押罪犯一样相互放置!
还有一篇博客写的比较麻烦,他把所有的点都并到一个集合里去,再用节点与代表元素的关系推出相互关系,比较麻烦
http://blog.csdn.net/c0de4fun/article/details/7318642/
vijos1531 食物链的更多相关文章
- 关押罪犯 and 食物链(并查集)
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...
- NOI2001|POJ1182食物链[种类并查集 向量]
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 65430 Accepted: 19283 Description ...
- tyvj1202 数数食物链
描述 TsyD学习了生物的生态环境那一张后,老师留了一项作业,就是给一张食物网,求所有食物链的总数.(从最低营养级生物(它不能吃任何其他的生物)开始到最高营养级(它不能被任何其他生物吃) 叫做一条食物 ...
- poj1182食物链_并查集_挑战程序设计竞赛例题
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 65534 Accepted: 19321 Description ...
- BZOJ4562: [Haoi2016]食物链
Description 如图所示为某生态系统的食物网示意图,据图回答第1小题 现在给你n个物种和m条能量流动关系,求其中的食物链条数. 物种的名称为从1到n编号 M条能量流动关系形如 a1 b1 a2 ...
- [poj1182]食物链(并查集+补集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 64841 Accepted: 19077 Description ...
- [并查集] POJ 1182 食物链
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 66294 Accepted: 19539 Description ...
- 【BZOJ-4562】食物链 记忆化搜索(拓扑序 + DP)
4562: [Haoi2016]食物链 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 133 Solved: 112[Submit][Status] ...
- POJ 1182 食物链(带权并查集)
传送门 食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 65579 Accepted: 19336 Descri ...
随机推荐
- Linux 负载监控脚本
#!/bin/bash Date=`echo $(date +%Y\-%m\-%d\ %H:%M:%S)`HostName=`hostname`IP=`ifconfig eth0 | grep &qu ...
- [django/mysql] 使用distinct在mysql中查询多条不重复记录值的解决办法
前言:不废话.,直接进入正文 正文: 如何使用distinct在mysql中查询多条不重复记录值? 首先,我们必须知道在django中模型执行查询有两种方法: 第一种,使用django给出的api,例 ...
- MVC PartialView
参考 Updating an MVC Partial View with Ajax RenderPartial vs RenderAction vs Partial vs Action in MV ...
- 【原】迎接微信winphone 5.0 版本的IE10样式兼容
微信 Android 5.1 和 iPhone 5.1 已正式发布了,据说本12月底,微信将推出 Winphone 5.0版本,全面支持微信支付,它绑定 IE10 浏览器,那么做微信公众号的 H5 页 ...
- NOIP模拟赛20161007
%hzwer http://hzwer.com/7602.html 题目名称 “与” 小象涂色 行动!行动! 输入文件 and.in elephant.in move.in 输出文件 and.out ...
- 概率dp学习
预备知识 一.期望的数学定义 如果X 是一个离散的随机变量,输出值为 x1, x2, ..., 和输出值相应的概率为p1, p2, ... (概率和为 1), 那么期望值为E(x)=x1p1+x2p2 ...
- Mongodb学习笔记五(C#操作mongodb)
mongodb c# driver(驱动)介绍 目前基于C#的mongodb驱动有两种,分别是官方驱动(下载地址)和samus驱动(下载地址). 本次我们只演示官方驱动的使用方法. 官方驱动文档查看 ...
- LeetCode-70-Climbing Stairs
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...
- Code[VS] 3123 高精度练习之超大整数乘法
FFT 做 高精度乘法 #include <bits/stdc++.h> ); struct complex { double a, b; inline complex( , ) { a ...
- BZOJ 2120: 数颜色
2120: 数颜色 Time Limit: 6 Sec Memory Limit: 259 MBSubmit: 3623 Solved: 1396[Submit][Status][Discuss] ...