poj 1182 食物链 (并查集)
http://poj.org/problem?id=1182
关于并查集 很好的一道题,开始也看了一直没懂。这次是因为《挑战程序设计竞赛》书上有讲解看了几遍终于懂了。是一种很好的思路,跟网上其他的不太一样。
因为N和K很大,所以必须高效维护动物之间的关系,并快速判断是否产生了矛盾,并查集是维护 "属于同一组"的数据结构,,但是在本题中,并不是只有属于同一类的信息,
还有捕食关系的存在,因此需要开动脑筋维护这些关系。
对于每只动物 i 创建3个元素 i-A,i-B,i-C,并用着3×N个元素建立并查集。这个并查集维护如下信息:
i-x 表示 ”i属于种类 x“;
并查集里的每一组表示组内所有元素代表的情况都同时发生或不发生。
例如,如果i-A和j-B 在同一个组里,就表示如果i属于种类A那么j一定是属于种类B,如果j属于种类B,那么i一定属于种类A,因此,对于每一条信息,只需要按照下面进行操作就可以
第一种:x和y属于同一种类,合并x-A和y-A,x-B和y-B,x-C和y-C.
第二种:x吃y 合并x-A和y-B,x-B和y-C,x-C和y-A.
不过在合并之前,需要判断合并是否会产生矛盾,例如在第一种信息的情况下,需要检查比如x-A和y-B或者y-C是否在同一组的等信息。
#include <cstdio>
const int maxn = ; int par[maxn]; //父亲
int rank[maxn]; //树的高度 int N,K;
int T[maxn],X[maxn],Y[maxn]; //T是类型
//初始化n个元素
void init(int n) {
for(int i=; i<n;i++) {
par[i]=i;
rank[i]=;
}
}
//查询树的根
int find(int x) {
if(par[x]==x) {
return x;
}
else return par[x]=find(par[x]);
}
//合并x和y所属集合
void unite(int x,int y) {
x=find(x);
y=find(y);
if(x==y) return; if(rank[x] < rank[y]) {
par[x]=y;
} else {
par[y]=x;
if(rank[x]==rank[y]) rank[x]++;
}
}
//判断x 和y是否属于同一个 集合
bool same(int x,int y) {
return find(x) == find(y);
} void solve() {
//初始化并查集
//元素 x,x+N,x+2*N分别代表x-A,x-B,x-C
init(N*); int ans=;
for(int i=;i<K;i++) {
int t=T[i];
int x=X[i]-,y=Y[i]-;
if(x<||N<=x||y<||N<=y) { //不正确的编号
ans++;
// printf("%d %d\n",x,y);
continue;
} if(t==) {
//x和y属于同一类 并且每次都是3个集合一起合并,所以只需要判断一种情况即可。
if(same(x,y+N)||same(x,y+*N)) { //竟然x和y是同一种类,那么x和y+N,x和y+2N必定不能是同一种
ans++;
}
else { //合并 两个种类,注意我们不清楚 x和y具体是哪个种类,所以必须全部合并
unite(x,y);
unite(x+N,y+N);
unite(x+N*,y+N*);
}
}
else {
//x吃y
if(same(x,y)||same(x,y+*N)) { //x和y在同一组,或者是A,C的情况
ans++;
}
else { //A吃B,B吃C,C吃A
unite(x,y+N);
unite(x+N,y+*N);
unite(x+*N,y);
}
}
}
printf("%d\n",ans);
} int main() {
//freopen("a.txt","r",stdin);
scanf("%d%d",&N,&K);
for(int i=;i<K;i++)
{
scanf("%d%d%d",&T[i],&X[i],&Y[i]);
// printf("%d %d %d\n",T[i],X[i],Y[i]);
}
solve();
return ;
}
poj 1182 食物链 (并查集)的更多相关文章
- POJ 1182 食物链 [并查集 带权并查集 开拓思路]
传送门 P - 食物链 Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit ...
- poj 1182 食物链 并查集 题解《挑战程序设计竞赛》
地址 http://poj.org/problem?id=1182 题解 可以考虑使用并查集解决 但是并不是简单的记录是否同一组的这般使用 每个动物都有三个并查集 自己 天敌 捕食 并查集 那么在获得 ...
- POJ 1182 食物链(并查集的使用)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 81915 Accepted: 24462 Description ...
- poj 1182 食物链 并查集的又一个用法
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 41584 Accepted: 12090 Descripti ...
- POJ 1182食物链(并查集)
食物链Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 85474 Accepted: 25549Description动物王国中有三 ...
- POJ - 1182 食物链 并查集经典
思路:设r(x)表示节点x与根结点的关系,px表示x的根结点.记录每个节点与其父节点的关系,就能很方便知道每个节点以及和它的父节点的关系. struct node{ int par; //父亲节点 i ...
- poj——1182食物链 并查集(提升版)
因为是中文题,题意就不说了,直接说思路: 我们不知道给的说法中的动物属于A B C哪一类,所以我们可以用不同区间的数字表示这几类动物,这并不影响结果,我们可以用并查集把属于一类的动物放在一块,举个例子 ...
- POJ 1182 食物链 (并查集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 50601 Accepted: 14786 Description ...
- POJ 1182 食物链(并查集)
题目链接 经过宝哥的讲解,终于对这种问题有了进一步的理解.根据flag[x]和flag[y]求flag[tx]是最关键的了. 0吃1,1吃2,2吃0. 假设flag[tx] = X; 那么X + fl ...
- poj 1182 (关系并查集) 食物链
题目传送门:http://poj.org/problem?id=1182 这是一道关系型并查集的题,对于每个动物来说,只有三种情况:同类,吃与被吃: 所以可以用0,1,2三个数字代表三种情况,在使用并 ...
随机推荐
- 成为嵌入式程序员应知道的0x10个基本问题
预处理器(Preprocessor)1 . 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #define SECONDS_PER_YEAR (60 * 60 * 2 ...
- 【BZOJ】【3164】【HEOI2013】Eden的博弈问题
树形DP 这题在考场上直接写的TreeDP……当时也没想出一个像样的暴力来对拍……好像只能这么直接做了……? 都说是博弈树了,转移关系都给的这么直接了……也没啥难度了吧= =(怪不得大家都不愿意写题解 ...
- 【BZOJ】【1018】【SHOI2008】堵塞的交通traffic
线段树 这题的线段树+分类讨论蛮神奇的……我以前学的线段树简直就是渣渣QAQ 看了下ydc题解里的思想>_>用线段树维护连通性!那么就自己写吧……每个节点表示一段区间的连通性(我的叶子节点 ...
- HDU1058Humble Numbers
Humble Numbers Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u ...
- ASP.NET运行机制之一般处理程序(ashx)
一. 概述 新建一个ashx文件 代码如下 <%@ WebHandler Language="C#" Class="TestHandler" %> ...
- no module named firefly.master.master
因为没有安装firefly python setup.py install
- POJ 1978
#include <iostream> #define MAXN 55 using namespace std; int _m[MAXN]; int tem[MAXN]; void cop ...
- Hibernate3.6中文手册
前言 1. 教程 1.1. 第一部分 - 第一个 Hibernate 应用程序 1.1.1. 设置 1.1.2. 第一个 class 1.1.3. 映射文件 1.1.4. Hibernate 配置 1 ...
- PHP 判断是否包含某字符串
PHP语言是一个功能强大的嵌入式HTML脚本语言,它的易用性让许多程序员选择使用.PHP判断字符串的包含,可以使用PHP的内置函数 strstr,strpos,stristr直接进行判断.也可以通过e ...
- 【LA3942-Remember the word 】Trie
http://acm.hust.edu.cn/vjudge/problem/22109 题意:给定n个单词,一个字符串,问把这个字符串划分为若干个单词的连接(单词可重复使用)有多少种方案(mod200 ...