POJ 1182 食物链(加权并查集)
2016-02-24 09:35
369 查看
思路:如果比较两动物之间的关系的话,肯定需要判断一下是否有关系,然后又有什么关系,这个有什么关系的话可以用一个r[]数组表示。
如果两动物有关系k==1&&r[a]!=r[b]一定是假话,k==2,那么r[a]的级别一定是r[b]之前即(r[a]+1)%3==r[b],否则是假话。
如果两者没关系,那么去创建并查集f[]和r[]. 一、要合并首先要查找两者祖先,同时在查找祖先,将经过的节点值回溯给f[x],同时更新r[x],r[x]是在回溯的时候从更早的祖先一点的回退到较晚的祖先,所以我们可以将一个更早祖先的值记录,r[x]=(r[x]+r[t])%3,(t为更早祖先的值)。 二、完成合并,在进行节点的合并时,注意将两种动物合成一到固定的树上,同时更新r[],那么在两棵树进行合并的时候又怎么更新r[]呢?
![](https://img-blog.csdn.net/20160224092217930)
(这里的x,y,是程序中的a,b;fx,fy是x,y;)
前提我们可以定义三种关系 a b同及为0,a倍b吃为2,b倍a吃为1.
我们可以画出一个正方形
a b
x y 最终我们要x->y所以依次y->bb->aa->xx->y知道他们的关系。a->x,为r[a].
如果两动物有关系k==1&&r[a]!=r[b]一定是假话,k==2,那么r[a]的级别一定是r[b]之前即(r[a]+1)%3==r[b],否则是假话。
如果两者没关系,那么去创建并查集f[]和r[]. 一、要合并首先要查找两者祖先,同时在查找祖先,将经过的节点值回溯给f[x],同时更新r[x],r[x]是在回溯的时候从更早的祖先一点的回退到较晚的祖先,所以我们可以将一个更早祖先的值记录,r[x]=(r[x]+r[t])%3,(t为更早祖先的值)。 二、完成合并,在进行节点的合并时,注意将两种动物合成一到固定的树上,同时更新r[],那么在两棵树进行合并的时候又怎么更新r[]呢?
(这里的x,y,是程序中的a,b;fx,fy是x,y;)
前提我们可以定义三种关系 a b同及为0,a倍b吃为2,b倍a吃为1.
我们可以画出一个正方形
a b
x y 最终我们要x->y所以依次y->bb->aa->xx->y知道他们的关系。a->x,为r[a].
#include<map> #include<queue> #include<cmath> #include<iostream> #include<cstdio> #include<stack> #include<cstring> #include<algorithm> #define LL __int64 #define inf 0x3f3f3f3f const double PI=acos(-1.0); using namespace std; int f[1000000],r[1000000]; int fi(int x){ if(x==f[x]) return x; int t; t = f[x]; f[x]=fi(f[x]); r[x] = (r[x] + r[t] )%3; return f[x]; } void mer(int a,int b,int k){ int x=fi(a); int y=fi(b); f[y]=x; r[y]=(r[a]-r[b]+k-1+3)%3; } int main(){ int n,m,i,j,k,a,b,ans; scanf("%d%d",&n,&m); ans=0; for(i=1;i<=n;++i){ f[i]=i; r[i]=0; } for(i=1;i<=m;++i){ scanf("%d%d%d",&k,&a,&b); if(a>n||b>n||(k==2&&a==b)){ ans++;continue; } if(fi(a)==fi(b)){ if( k==1&&r[a]!=r[b] ) ans++; else if(k==2&&(r[a]+1)%3!=r[b] ) ans++; } else{ mer(a,b,k); } } printf("%d\n",ans); return 0; }
相关文章推荐
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- 用单调栈解决最大连续矩形面积问题
- 2632 Crashing Robots的解决方法
- 1573 Robot Motion (简单题)
- HDU-1213-How Many Tables
- POJ——3253 Fence Repair