NOI2001|POJ1182食物链[种类并查集 向量]
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 65430 | Accepted: 19283 |
Description
现有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
以下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食物链[种类并查集 向量]的更多相关文章
- POJ1182 食物链 —— 种类并查集
题目链接:http://poj.org/problem?id=1182 食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: ...
- poj1182(种类并查集好题)
不得不说,我得感谢@驱动幽灵百鬼夜行小肆,正是因为看明白了他给出的解析,我才完全弄懂种类并查集的,这里,我也不想去改其他的,就直接引用他的解题报告吧 转载:http://blog.csdn.net/c ...
- P2024 [NOI2001]食物链(种类并查集)
题目链接: https://www.luogu.org/problemnew/show/P2024 题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 ...
- POJ1182 食物链(并查集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 55260 Accepted: 16210 Description ...
- POJ1182食物链(并查集)
Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到 ...
- POJ-1182 食物链(并查集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 75814 Accepted: 22528 Description ...
- poj1182 食物链【并查集-好题!】
动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两 ...
- POJ1182食物链 (并查集)
第一反应就是和那个搞基的虫子的题很像(poj2492 http://www.cnblogs.com/wenruo/p/4658874.html),不过是把种类从2变成了3. 错在很白痴的地方,卡了好久 ...
- poj1182 食物链(并查集 好题)
https://vjudge.net/problem/POJ-1182 并查集经典题 对于每只动物创建3个元素,x, x+N, x+2*N(分别表示x属于A类,B类和C类). 把两个元素放在一个组代表 ...
随机推荐
- C# 工作中遇到的几个问题
C# 工作中遇到的几个问题 1.将VS2010中的代码编辑器的默认字体“新宋体”改为“微软雅黑”后,代码的注释,很难对齐,特别是用SandCastle Help File Builder生成帮助文档 ...
- csharp: ODP.NET,System.Data.OracleClient(.net 4.0) and System.Data.OleDb读取Oracle g 11.2.0的区别
ODP.NET: 引用: using Oracle.DataAccess; //Oracle g 11.2.0 using Oracle.DataAccess.Client; using Oracle ...
- 开源UML工具推荐
1.StarUML StarUML是一个开源UML项目,可以开发快速,灵活,可扩展,多功能并且免费的UML/MDA平台.此项目运行在Win32平台之上.StarUML项目的目标是成为RationalR ...
- C标准头文件<string.h>
里面主要包含了一些与字符串关联的函数的声明,这些函数有如下的命名规则: 以"mem"开头的函数操作任意的字符序列 以"strn"开头的函数操作非空字符序列 以& ...
- ABP Migration(数据库迁移)
今天准备说说EntityFramework 6.0+,它与我之前所学的4.0有所区别,自从4.1发布以来,code first 被许多人所钟爱,Dbcontext API也由此时而生.早在学校的时候就 ...
- 23、ASP.NET MVC入门到精通——业务层和数据层父类及接口-T4模板
本系列目录:ASP.NET MVC4入门到精通系列目录汇总 在上一篇中,我们已经把项目的基本框架搭起来了,这一篇我们就来实现业务层和数据层的父接口及父类. 1.我们先来定义一个业务层父接口IBaseB ...
- Xdebug文档(五) 代码覆盖分析
代码覆盖分析能在请求时让你知道脚本哪一行(或哪一段)在执行. 相关设置 xdebug.coverage_enable 类型: boolean, 默认值: 1, 始于 Xdebug >= 2.2 ...
- 【特别推荐】小伙伴们惊呆了!8个超炫的 Web 效果
CodePen 是一个在线的 HTML.CSS 和 JavaScript 代码编辑器,能够编写代码并即时预览效果.你在上面可以在线展示自己的作品,也可以看到其他人在网页中实现的各种令人惊奇的效果. 今 ...
- 设计一个自动生成棋盘格子的JS小程序
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- MYSQL进阶,新手变司机
一.视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用. SELECT * FROM ( S ...