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 食物链 (并查集)的更多相关文章

  1. POJ 1182 食物链 [并查集 带权并查集 开拓思路]

    传送门 P - 食物链 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit  ...

  2. poj 1182 食物链 并查集 题解《挑战程序设计竞赛》

    地址 http://poj.org/problem?id=1182 题解 可以考虑使用并查集解决 但是并不是简单的记录是否同一组的这般使用 每个动物都有三个并查集 自己 天敌 捕食 并查集 那么在获得 ...

  3. POJ 1182 食物链(并查集的使用)

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

  4. poj 1182 食物链 并查集的又一个用法

    食物链   Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 41584   Accepted: 12090 Descripti ...

  5. POJ 1182食物链(并查集)

    食物链Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 85474 Accepted: 25549Description动物王国中有三 ...

  6. POJ - 1182 食物链 并查集经典

    思路:设r(x)表示节点x与根结点的关系,px表示x的根结点.记录每个节点与其父节点的关系,就能很方便知道每个节点以及和它的父节点的关系. struct node{ int par; //父亲节点 i ...

  7. poj——1182食物链 并查集(提升版)

    因为是中文题,题意就不说了,直接说思路: 我们不知道给的说法中的动物属于A B C哪一类,所以我们可以用不同区间的数字表示这几类动物,这并不影响结果,我们可以用并查集把属于一类的动物放在一块,举个例子 ...

  8. POJ 1182 食物链 (并查集)

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

  9. POJ 1182 食物链(并查集)

    题目链接 经过宝哥的讲解,终于对这种问题有了进一步的理解.根据flag[x]和flag[y]求flag[tx]是最关键的了. 0吃1,1吃2,2吃0. 假设flag[tx] = X; 那么X + fl ...

  10. poj 1182 (关系并查集) 食物链

    题目传送门:http://poj.org/problem?id=1182 这是一道关系型并查集的题,对于每个动物来说,只有三种情况:同类,吃与被吃: 所以可以用0,1,2三个数字代表三种情况,在使用并 ...

随机推荐

  1. 二分--1043 - Triangle Partitioning

    1043 - Triangle Partitioning PDF (English) Statistics Forum Time Limit: 0.5 second(s) Memory Limit:  ...

  2. Posix线程编程指南(1) 线程创建与取消

    线程创建 1.1 线程与进程 相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列.在串行程序基础上引入线程和进程是为了提高程序的 ...

  3. javascript 字符串和json的互转

    FROM:http://www.cnblogs.com/mizzle/archive/2012/02/10/2345891.html 在数据传输过程中,json是以文本,即字符串的形式传递的,而JS操 ...

  4. 在C语言中嵌入汇编语言

    TMS320C28x编译器允许在C程序中嵌入汇编指令,通过下面声明实现: asm(“assembler text”); 其中assembler text指汇编代码.asm指令一般用来处理C/C++语句 ...

  5. .NET设计模式(15):结构型模式专题总结(转)

    摘要:结构型模式,顾名思义讨论的是类和对象的结构,它采用继承机制来组合接口或实现(类结构型模式),或者通过组合一些对象,从而实现新的功能(对象结构型模式).这些结构型模式,它们在某些方面具有很大的相似 ...

  6. ios 设计软件

    briefs V1.0.5 download @ here:http://soft.macx.cn/5442.htm 密码:www.macx.cn

  7. 使用CSS3实现3D图片滑块效果

    使用 CSS3 的3D变换特性,我们可以通过让元素在三维空间中变换来实现一些新奇的效果. 这篇文章分享的这款 jQuery 立体图片滑块插件,利用了 3D transforms(变换)属性来实现多种不 ...

  8. Visual Studio 2015支持为Linux构建应用

    点这里 微软著名的集成开发环境有可能是首次在其产品页提及了竞争对手Linux.Visual Studio 2015的页面声称,“Build for iOS, Android, Windows devi ...

  9. C#调用脚本语言(三)-- IronJS 与 IronLua 简单方法性能比较

    1.   测试环境 1.1. 硬件环境 CPU:intel Core i7-740QM 内存:8GDDR3 Memory 1.2. 系统 系统:Windows 8 Enterprise 开发工具:Vs ...

  10. ExtJs布局之viewport

    <!DOCTYPE html> <html> <head> <title>ExtJs</title> <meta http-equiv ...