食物链
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 65430   Accepted: 19283

Description

动物王国中有三类动物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),输出假话的总数。 

Input

第一行是两个整数N和K,以一个空格分隔。 
以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。 
若D=1,则表示X和Y是同类。 
若D=2,则表示X吃Y。

Output

只有一个整数,表示假话的数目。

Sample Input

100 7
1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5

Sample Output

3

多了一种关系的种类并查集
v[i] 0和根同类 1吃根 2被根吃
可以发现1->0->2->1.....
可以从向量的角度思考,比如x->y +3%3是1的话说明x吃y
v[x]就是x->fa[x]这个向量的值
发现D-1正好描述了X->Y这个向量的关系
路径压缩和合并的时候都画图用向量推一下就可以了

还有一种做法,是对每个动物x建立3个集合:x表示与x同类的动物,x+n表示要x吃的动物,x+2*n表示吃x的动物。

一些理解
并查集就是维护了一些关系
种类并查集是把知道关系的东西合并,通过分配一个值来处理
另一种做法是把同一类合并
//
// main.cpp
// poj1182
//
// Created by Candy on 31/10/2016.
// Copyright ? 2016 Candy. All rights reserved.
// #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=5e4+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,m,c,x,y,ans=;
int fa[N],v[N];
inline int find(int x){
if(x==fa[x]) return x;
int root=find(fa[x]);
v[x]=(v[x]+v[fa[x]])%;//x->fa[x] + fa[x]->root
return fa[x]=root;
}
inline int unn(int x,int y,int op){
int f1=find(x),f2=find(y);
if(f1==f2){
if((-v[y]+v[x]+)%!=op) return ;
}else{
fa[f1]=f2;
v[f1]=(op+v[y]-v[x]+)%;
}
return ;
}
int main(int argc, const char * argv[]) {
n=read();m=read();
for(int i=;i<=n;i++) fa[i]=i,v[i]=;
for(int i=;i<=m;i++){
c=read();x=read();y=read();
if(x>n||y>n||(c==&&x==y)){ans++;continue;}
ans+=unn(x,y,c-);
}
printf("%d",ans);
return ;
}
来自luogu题解,另一种做法
这题显然要用并查集。因为只有3种动物,我的方法是对每个动物x建立3个集合:x表示与x同类的动物,x+n表示要x吃的动物,x+*n表示吃x的动物。 对于每个读入的描述D X Y,做以下处理: 如果X或Y不再区间[,n]中,这句是假话。 D为1
如果x+n或x+*n与y在同一个集合中说明已知x和y不是同一种动物,这句是假话; 否则,分别将x与y,x+n与y+n,x+*n与y+*n合并。 D为2
如果x与y在同一个集合中,说明已知x和y是同一种动物,这句是假话; 如果x+*n与y在同一个集合中,说明已知y吃x,这句是假话; 否则,分别将x与y+*n,x+n与y,x+*n与y+n合并。 <hr> 说起来很复杂,实现起来其实很简单,代码见下: #include<iostream>
#include<algorithm>
using namespace std;
int p[];
int Find(int x) { return x == p[x] ? x : p[x] = Find(p[x]); }
void Init(int n) { for (int i = ; i <= * n; i++) p[i] = i; }
void Union(int x, int y)
{
int xx = Find(x), yy = Find(y);
if (xx != yy) p[xx] = yy;
}
int main()
{
int n, k, ans = ;
cin >> n >> k;
Init(n);
for (int i = ; i <= k; i++)
{
int a, x, y;
cin >> a >> x >> y;
if (x > n || y > n || x < || y < ) { ans++; continue; }
if (a == )
{
if (Find(x + n) == Find(y) || Find(x + * n) == Find(y)) { ans++; continue; }
Union(x, y);
Union(x + n, y + n);
Union(x + * n, y + * n);
}
else
{
if (Find(x) == Find(y) || Find(x + * n) == Find(y)) { ans++; continue; }
Union(x, y + * n);
Union(x + n, y);
Union(x + * n, y + n);
}
}
cout << ans;
}

NOI2001|POJ1182食物链[种类并查集 向量]的更多相关文章

  1. POJ1182 食物链 —— 种类并查集

    题目链接:http://poj.org/problem?id=1182 食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: ...

  2. poj1182(种类并查集好题)

    不得不说,我得感谢@驱动幽灵百鬼夜行小肆,正是因为看明白了他给出的解析,我才完全弄懂种类并查集的,这里,我也不想去改其他的,就直接引用他的解题报告吧 转载:http://blog.csdn.net/c ...

  3. P2024 [NOI2001]食物链(种类并查集)

    题目链接: https://www.luogu.org/problemnew/show/P2024 题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 ...

  4. POJ1182 食物链(并查集)

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

  5. POJ1182食物链(并查集)

    Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到 ...

  6. POJ-1182 食物链(并查集)

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

  7. poj1182 食物链【并查集-好题!】

    动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A.  现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两 ...

  8. POJ1182食物链 (并查集)

    第一反应就是和那个搞基的虫子的题很像(poj2492 http://www.cnblogs.com/wenruo/p/4658874.html),不过是把种类从2变成了3. 错在很白痴的地方,卡了好久 ...

  9. poj1182 食物链(并查集 好题)

    https://vjudge.net/problem/POJ-1182 并查集经典题 对于每只动物创建3个元素,x, x+N, x+2*N(分别表示x属于A类,B类和C类). 把两个元素放在一个组代表 ...

随机推荐

  1. oracle函数大全(转载)

    F.1字符函数--返回字符值 这些函数全都接收的是字符族类型的参数(CHR除外)并且返回字符值.除了特别说明的之外,这些函数大部分返回VARCHAR2类型的数值.字符函数的返回类型所受的限制和基本数据 ...

  2. 51nod 算法马拉松18 A 染色问题

    染色问题 基准时间限制:1 秒 空间限制:10240 KB 分值: 40 一个n(3<=n<=100)个点的完全图,现在给出n,要求将每条边都染上一种颜色k(1<=k<=n), ...

  3. AdapterPattern(适配器模式)

    import org.omg.PortableServer.AdapterActivator; /** * 分两种情况: * 1.类适配器 * 2.对象适配器 * 作用:让原本接口不兼容的两个类可以在 ...

  4. 关于依赖注入IOC/DI的感想

    之前一直不明白依赖注入有什么好处,甚至觉得它是鸡肋,现在想想,当时真是可笑. 这个想法正如同说接口是没有用处一样. 当整个项目非常庞大,各个方法之间的调用非常复杂,那么,可以想象一下,假设说没有任何的 ...

  5. HTML5定稿

    HTML5定稿了,终于有一种编程语言开发的程序可以在Android和IOS两种设备上运行了 本文转载自: http://www.cnblogs.com/tuyile006/p/4103634.html ...

  6. 装配bean

    spring有三种装配bean的方式:隐式装配.java代码装配.xml装配 隐式装配最为省事方便,也称为自动化装配 这三种装配方式可以混搭着来用 在这里通过一个例子来讲述配置 CD的两个实现,一个是 ...

  7. 【小贴士】【stringify神BUG】【localstorage失效】【消灭Safari alert框】【是否延迟加载】【页面10px白屏】

    前言 最近碰到几个恶心问题,也发现一点优化技巧,以及对Hybrid知识的一些整理,这里便一并拿出来做分享了,关于Hybrid的调试,会是我今后一个重点 我的博客首先是学习笔记,方便自己做知识沉淀,以后 ...

  8. JQuery 实现两列等高并自适应高度

    想要使用 JQuery 实现两列等高并自适应高度,其实也很简单,原理就是取得左右两边的高度,然后判断这个值,把大的值赋给小的就行了.看代码: $(document).ready(function() ...

  9. chrome 调试 SASS

    第一步: 执行sass预编译命令 先来我的项目文件夹结构: ->进入sass /css文件下->打开cmd命令 ->输入sass --watch --scss  test.scss: ...

  10. 商业智能SAAS走向中小企业

    20多年前,Gartner提出了商业智能的概念,并将其定义为“一类由数据仓库.查询报表.数据分析.数据挖掘等部分组成的,以帮助企业决策的技术及应用”.从技术上讲,商业智能是数据仓库.OLAP和数据挖掘 ...