poj1182食物链(带权并查集)
2015-05-10 11:38
246 查看
///基本思路:带权并查集(简单的理解就是将有关系的点合并到一个集合,记录每个点到集合根节点的权重)
#include <iostream> #include <cstdio> #include <cstring> #define MAX 50010 using namespace std; int par[MAX];///记录集合根节点 int offset[MAX];///记录每个节点到根节点的偏移量 int n,m; void make_set() { for(int i=1; i<=n; ++i) { par[i]=i; offset[i]=0;///相对于根的偏移量 } } int find_set(int x) { if(x!=par[x]) { int tmp=find_set(par[x]); offset[x]=(offset[par[x]]+offset[x])%3;///关键点1 par[x]=tmp; } return par[x]; } void union_set(int x,int y,int v) { int tmp1=find_set(x); int tmp2=find_set(y); par[tmp2]=tmp1; offset[tmp2]=(offset[x]-offset[y]+v+3)%3;///关键点2 } int main() { scanf("%d%d",&n,&m); make_set(); int d,a,b; int ans=0; for(int i=1; i<=m; i++) { scanf("%d%d%d",&d,&a,&b); if(a>n||b>n) { ans++; continue; } if(d==1) { if(find_set(a)==find_set(b)) if((offset[b]-offset[a]+3)%3!=0) ans++; else union_set(a,b,0); } else if(d==2) { if(a==b) { ans++; continue; } if(find_set(a)==find_set(b)) { if((offset[b]-offset[a]+3)%3==1); else ans++; } else union_set(a,b,1); } } printf("%d\n",ans); return 0; }
相关文章推荐
- POJ1182食物链之并查集解法
- poj1182食物链_并查集_挑战程序设计竞赛例题
- poj1182食物链(种类,带权并查集)
- 并查集专辑 (poj1182食物链,hdu3038, poj1733, poj1984, zoj3261)
- 并查集-POJ1182食物链
- POJ1182食物链,HDU1829(种类并查集)
- POJ1182食物链【并查集+根节点的偏移】
- POJ1182食物链 (并查集)
- POJ1182食物链,HDU1829(种类并查集)
- poj1182食物链,经典带权并查集
- poj1182食物链(并查集)
- POJ1182食物链(并查集经典好题)
- poj1182食物链(带权并查集+路径压缩)
- poj1182食物链 (并查集)
- poj1182食物链(种类并查集)
- 带权并查集模板(poj1182食物链验证)
- poj1182食物链 种类并查集
- poj1182食物链(带权并查集)
- poj1182食物链(并查集)
- poj1182食物链(种类并查集)