POJ1182-并查集
来源:互联网 发布:网络远程教育哪家好 编辑:程序博客网 时间:2024/05/18 18:43
这题有一个关键点: x的食物的食物以x为食,即生物间的关系是以3为循环的,就像运算 (0+1)%3=1,(1+1)%3=2,(2+1)%3=0,(0+1)%3=1... ...
不管d=1还是d=2,都表示x与y有关系,因此可以并到一个并查集里去,然而具体的同类与捕食关系可用0,1,2来代表;
这里以r[i]表示i与其并查集中父节点p[i]的关系: 0表示同类,1表示i吃p[i],2表是i被p[i]吃;
那么如果x和y在同一个并查集时,可通过查询x与根节点的关系,y与根节点的关系来判断x与y的关系。若在并查集的find操作中压缩路径的话,根节点也就成了父节点,好方便!
另外合并和查找时可以利用一些加法,对3取模的运算来更新r。
AC代码:
#include <cstdio>#include <cstring>#include <iostream>using namespace std;const int NN=50005;int n;int p[NN]; //根节点int r[NN]; //与父节点的关系,0:同类,1:吃根节点,2:被根节点吃inline void get(int &x){ char c=getchar(); while (c<'0' || c>'9') c=getchar(); x=c-'0'; c=getchar(); while (c>='0' && c<='9') x=x*10+c-'0',c=getchar();}int find(int x){ if (p[x]!=x) { int t=p[x]; p[x]=find(p[x]); r[x]=(r[x]+r[t])%3; //x与新父节点(根节点)的关系 } return p[x];}int Union(int d,int x,int y){ int fx=find(x); int fy=find(y); p[fx]=fy; r[fx]=(r[y]-r[x]+2+d)%3; //fx与fy的关系=y与fy的关系和x与fx的关系差+x与y的关系}int main(){ int d,x,y,k,cnt=0; scanf("%d%d",&n,&k); for (int i=1; i<=n; i++) { p[i]=i; r[i]=0; } while (k--) { get(d); get(x); get(y); if (x>n || y>n) cnt++; else if (d==2 && x==y) cnt++; else if (find(x)!=find(y)) Union(d,x,y); else if ((r[y]+d+2)%3!=r[x]) cnt++;//这句话一定是在find(x)和find(y)之后的,因为find过后r[x]才是x与其根节点的关系 } printf("%d\n",cnt); return 0;}
- 并查集 poj1182
- POJ1182-并查集
- poj1182----并查集
- 并查集--poj1182
- 并查集&poj1182
- poj1182(并查集)
- 食物链 POJ1182 -- 并查集
- poj1182 食物链 (并查集)
- poj1182 并查集 食物链
- poj1182食物链 并查集
- poj1182 种类并查集
- poj1182+hdu1892(并查集)
- poj1182 并查集
- poj1182 种类并查集
- 并查集-POJ1182食物链
- POJ1182 - 食物链 - 并查集
- 并查集 食物链 POJ1182
- poj1182 食物链(并查集)
- hdu 1568 Fib数通项公式 求某个数的前4位
- 基于 Win32 的应用程序
- apache的ssl加密传输
- Java多线程设计模式
- Window Services中如何进行调试
- POJ1182-并查集
- WDK/DDK :warning treated as error
- Linux下进程间通信
- Web开发者看过来,Meteor开发框架为你带来下一代高品质实时Web App开发的新模式
- linux c socket
- 关于BW Query Performance 的一些问答
- 详解Android动画之Tween Animation
- android解决中文乱码的所有方案
- Linux 内核配置方式详解