poj 1182 食物链(DSU)
2016-03-07 08:58
330 查看
①普通并查集:
f[i]=i,表示i属于A
f[i]=i+n,表示i属于B
f[i]=i+2*n,表示i属于C
每次合并之前先进行判断
如果x和y属于同类,则需要判断(x,y+n)和(x,y+2*n)
如果x吃y,则需要判断(x,y)和(x+2*n,y)
②带权并查集:
每次合并压缩路径的时候, 模三取余,然后判断权值即可
附上普通并查集的代码:
f[i]=i,表示i属于A
f[i]=i+n,表示i属于B
f[i]=i+2*n,表示i属于C
每次合并之前先进行判断
如果x和y属于同类,则需要判断(x,y+n)和(x,y+2*n)
如果x吃y,则需要判断(x,y)和(x+2*n,y)
②带权并查集:
每次合并压缩路径的时候, 模三取余,然后判断权值即可
附上普通并查集的代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> using namespace std; const int INF=0x3f3f3f3f; const int maxn=50005; int n,k; int f[3*maxn]; void Make_Set(){ int Max=3*n; for(int i=0;i<Max;i++){ f[i]=i; } } int find(int x){ return x==f[x]?x:f[x]=find(f[x]); } void Union(int x,int y){ int rx=find(x); int ry=find(y); f[ry]=f[rx]; } bool judge(int x,int y){ return find(x)==find(y); } int main(){ #ifndef ONLINE_JUDGE freopen("test.in","r",stdin); freopen("test.out","w",stdout); #endif scanf("%d%d",&n,&k); Make_Set(); int res=0; int op,x,y; while(k--){ scanf("%d%d%d",&op,&x,&y); x--,y--; if(x<0||x>=n||y<0||y>=n) {res++;continue;} if(op==1){ if(judge(x,y+n)||judge(x,y+2*n)) res++; else{ Union(x,y); Union(x+n,y+n); Union(x+2*n,y+2*n); } } else{ if(judge(x,y)||judge(x,y+2*n)) res++; else{ Union(x,y+n); Union(x+n,y+2*n); Union(x+2*n,y); } } } printf("%d\n",res); return 0; }
相关文章推荐
- ExtJs.Store.load()各参数含义解析
- C/C++从文件末尾反向获取指定N行数据
- 自我介绍
- Windows CE创建桌面快捷方式
- Android Volley完全解析(四),带你从源码的角度理解Volley
- 链表末尾插入新元素
- Ubuntu 14.04安装配置NFS服务器
- 经典软件推荐:AppVerifier(应用程序验证器)
- Python 正则表达式辨析,原始字符串
- 【ARM-Linux开发】Linux的SOCKET编程详解
- sencha app build之后,无法更新应用程序
- 【DataStructure】Description and usage of queue
- spark1.1.0学习路线
- 自我介绍
- c#虚方法和抽象方法的区别
- 【VS开发】socket编程原理
- 对软件工程的疑问
- Android 6.0 新特性
- 【转】七个受用一生的心理寓言
- JS特殊符号