POJ 1182 (经典食物链 /并查集扩展)
向量偏移——由“食物链”引发的总结
http://poj.org/problem?id=1182这道食物链题目是并查集的变型。非常久曾经做的一次是水过的,这次细致地研究了这“食物链”,无非就是运用向量偏移。从曾经节点与节点转化成向量与向量的关系。我们能够把矛盾的产生得益于向量偏移时的结果。
直接引出向量偏移的运用。
以下是POJ一位大牛这样理解的,本人稍有改动。
对于集合里的随意两个元素a,b而言,它们之间必然存在着某种联系,由于并查集中的元素均是有联系的。否则也不会被合并到当前集合中。
那么我们就把这2个元素之间的关系量转化为一个偏移量。以食物链的关系而言。最好还是如果
a->b 偏移量0时 a和b同类
a->b 偏移量1时 a吃b
a->b 偏移量2时 a被b吃,也就是b吃a
有了这些基础,我们就能够在并查集中完毕随意两个元素之间的关系转换了。最好还是继续如果,a的当前集合根节点aa。b的当前集合根节点bb,a->b的偏移值为d-1(题中给出的询问已知条件)
(1)假设aa和bb不同样,那么我们把bb合并到aa上,而且更新delta[bb]值(delta[i]表示i的当前集合根节点到i的偏移量)
此时 aa->bb = aa->a + a->b + b->bb,可能这一步就是所谓向量思维模式吧
上式进一步转化为:aa->bb = (3-delta[a]+d-1+delta[b])%3 = delta[bb]。(模3是保证偏移量取值始终在[0,2]间)
以图示表示为:
(2)假设aa和bb同样,那么我们就验证a->b之间的偏移量是否与题中给出的d-1一致
此时 a->b = a->aa + aa->b = a->aa + bb->b,
上式进一步转化为:a->b = (3+delta[a]-delta[b])%3,若一致则为真。否则为假。
以图示表示为:
一般化总结:
并查集的偏移向量属于并查集的变形,仅仅要适用于集合数目较少,或是固定的并查集类型。
#include<iostream>
#include<cstdio>
#define maxn 50001
using namespace std; int uset[maxn],rel[maxn]; int find_uset(int x)
{
if(uset[x]!=x)
{
int k=uset[x]; //先写
uset[x]=find_uset(uset[x]); //注意上下两处。由于递归调用循序的原因。 rel[x]=(rel[k]+rel[x])%3; //后写。
}
return uset[x];
} int make_uset(int x,int y,int d)
{
int ux,uy;
if((ux=find_uset(x))==(uy=find_uset(y)))
{
if((3+rel[x]-rel[y])%3!=(d-1))
return 1;
return 0;
}
else
{
uset[ux]=uy;
rel[ux]=(3-rel[x]+d-1+rel[y])%3;
return 0;
}
} int main()
{
int n,k;
scanf("%d%d",&n,&k); int d,x,y,cnt=0;
for(int i=1;i<=n;i++)
{
uset[i]=i;
rel[i]=0;
}
for(int i=0;i<k;i++)
{
scanf("%d%d%d",&d,&x,&y);
if(x>n||y>n||(d==2&&x==y))
cnt++;
else if(make_uset(x,y,d))
cnt++;
} printf("%d\n",cnt); return 0;
}
POJ 1182 (经典食物链 /并查集扩展)的更多相关文章
- poj 1182 (带权并查集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 71361 Accepted: 21131 Description ...
- 洛谷 P2024 食物链 POJ 1182 Label:并查集Turbo
题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个动物都是 A,B,C 中的一种,但是我 ...
- 食物链 POJ 1182(种类并查集)
Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到 ...
- POJ1182 食物链---(经典种类并查集)
题目链接:http://poj.org/problem?id=1182 食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submission ...
- poj 1611 :The Suspects经典的并查集题目
Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized ...
- 编程算法 - 食物链 并查集 代码(C)
食物链 并查集 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 有N仅仅动物, 分别编号为1,2,...,N. 全部动物都属于A,B,C中的一种 ...
- POJ - 1182 食物链 并查集经典
思路:设r(x)表示节点x与根结点的关系,px表示x的根结点.记录每个节点与其父节点的关系,就能很方便知道每个节点以及和它的父节点的关系. struct node{ int par; //父亲节点 i ...
- POJ 1182 食物链 [并查集 带权并查集 开拓思路]
传送门 P - 食物链 Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit ...
- poj 1182 食物链 并查集 题解《挑战程序设计竞赛》
地址 http://poj.org/problem?id=1182 题解 可以考虑使用并查集解决 但是并不是简单的记录是否同一组的这般使用 每个动物都有三个并查集 自己 天敌 捕食 并查集 那么在获得 ...
随机推荐
- android SurfaceView绘制 重新学习--控制动画移动
直接上demo,图是自己切的,将就用吧.点击左右两边分别向左右移动. public class MySurfaceView extends SurfaceView implements Callbac ...
- 推荐一款不错的GIF录制软件附带.NET源码
源码下载地址:http://www.51aspx.com/Code/ScreenToGif10
- uva 11992 - Fast Matrix Operations
简单的线段树的题: 有两种方法写这个题,目前用的熟是这种慢点的: 不过不知道怎么老是T: 感觉网上A过的人的时间度都好小,但他们都是用数组实现的 难道是指针比数组慢? 好吧,以后多用数组写写吧! 超时 ...
- EasyUI 调用getSelections方法只能获取到一行的原因
$('#tt').datagrid({ url: 'GetDataJosn', title: 'DataGrid', width: 800, height: 300, pageSize: 10, id ...
- 【BZOJ 2154】Crash的数字表格 (莫比乌斯+分块)
2154: Crash的数字表格 Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能 ...
- elevation 和 translationZ的区别
Z轴阴影: Z = elevation + translationZ elevation 是静态值,是View在Z轴上的初始值 translationZ是动态值,是Z上的偏移变化 参考 http:// ...
- Highcharts实例
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...
- 浅析五大ASP.NET数据控件
转自:http://kb.cnblogs.com/page/69207/ 摘要:ASP.NET中有不少的控件,在这当中有一部分是用来处理数据的控件.在这里我们正要讨论的就是ASP.NET数据控件,希望 ...
- PHP重构之函数上移
参考<重构> <?php abstract class Customer { public function addBill($date, $amount) { echo " ...
- HNOI 2008:水平可见直线
Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为 可见的,否则Li为被覆盖的. 例如,对于直线: L1:y ...