poj1182(食物链)----带权并查集
2016-07-23 11:19
253 查看
这道题,刚开始开了3个并查集,各种关系把我搞得头晕,已提交就是wa,怎么也找不出错误,上网查题解发现是并查集姿势不对!!!
只需开一个并查集,只要能确定关系就扔进并查集里,其中每个元素与老大哥的关系无非三种:同类,被吃,吃人,分别用0,1,2来表示。
那么每来一次判断,先判断两个是否有关系,没关系就肯定是真话,join;
否则就得判断是否说谎;
d==1且ta与tb是同类,没说谎
d==2且ta与tb满足
三种可能
ta tb
0 1
1 2
2 0
合起来就是(rt[tb]-rt[ta]+3)%3==1)
那么没说谎
其余情况都是说谎。
下一个难点就是join函数
(d==1) rt[fx]=(rt[y]-rt[x]+3)%3;
(d==2) rt[fx]=(rt[y]-rt[x]+2)%3;
按照上面那种思路就可以得出,不懂的话可以看一些其他blog
http://blog.csdn.net/c0de4fun/article/details/7318642
http://wxdlut.blog.163.com/blog/static/128770158200982754311269/
只需开一个并查集,只要能确定关系就扔进并查集里,其中每个元素与老大哥的关系无非三种:同类,被吃,吃人,分别用0,1,2来表示。
那么每来一次判断,先判断两个是否有关系,没关系就肯定是真话,join;
否则就得判断是否说谎;
d==1且ta与tb是同类,没说谎
d==2且ta与tb满足
三种可能
ta tb
0 1
1 2
2 0
合起来就是(rt[tb]-rt[ta]+3)%3==1)
那么没说谎
其余情况都是说谎。
下一个难点就是join函数
(d==1) rt[fx]=(rt[y]-rt[x]+3)%3;
(d==2) rt[fx]=(rt[y]-rt[x]+2)%3;
按照上面那种思路就可以得出,不懂的话可以看一些其他blog
http://blog.csdn.net/c0de4fun/article/details/7318642
http://wxdlut.blog.163.com/blog/static/128770158200982754311269/
#include <iostream> #include <stdio.h> #include <algorithm> #include <stdlib.h> #include <vector> #include <string.h> #include <queue> #define ms(X) memset(X,0,sizeof(X)) typedef long long LL; using namespace std; int pre[50005],rt[50005];//0表示pre[x]和x同类,1表示x被吃,2表示x吃人 int fnd(int node) { if(pre[node]==node) return node; int tmp=pre[node]; pre[node]=fnd(pre[node]); rt[node]=(rt[tmp]+rt[node])%3; return pre[node]; } void join(int x,int y,int d) { int fx=fnd(x),fy=fnd(y); if(fx!=fy) pre[fx]=fy; if(d==1) rt[fx]=(rt[y]-rt[x]+3)%3; else rt[fx]=(rt[y]-rt[x]+2)%3; } int main(int argc, char const *argv[]) { int n,k,cnt=0; cin>>n>>k; int d,ta,tb; ms(rt); for(int i=1;i<=n;i++) pre[i]=i; while(k--) { scanf("%d %d %d",&d,&ta,&tb); if(ta>n||tb>n||(ta==tb&&d==2)) {cnt++;continue;} if(fnd(ta)==fnd(tb)){ if(d==1&&rt[ta]==rt[tb]) continue; else if(d==2&&(rt[tb]-rt[ta]+3)%3==1) continue; else cnt++; } else join(ta,tb,d); } printf("%d",cnt ); return 0; }
相关文章推荐
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2159 Ancient Cipher
- 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
- [数论]poj2635__The Embarrassed Cryptographer
- [二分图匹配]poj2446__Chessboard
- POJ1050 最大子矩阵和
- 用单调栈解决最大连续矩形面积问题