您的位置:首页 > 其它

poj1182->食物连->并查集

2015-09-02 23:42 363 查看

poj1182 食物链

思路来源,但是有所不同,详细异同点代码中有注释。

并查集小结:并查集算法主要是根据元素之间的关系去快速查询(Query ),我们在将元素加入(Merge
)我们的并查集中时要实时的更新关系函数(Relation 数组),弄清楚谁是谁的父节点(GetPar),谁是谁们的根节点(Parent 数组)。

#include<cstdio>

using namespace std;

const int Max_num = 50005;
int n,k;
int Parent[Max_num];
int Relation[Max_num];

void Init(){
for(int i= 0;i<=n;i++){
Parent[i] = i;
//Relation[i] = 0 ->本身 1-> 吃掉父节点2->  被父节点吃掉
Relation[i] = 0;
}
}

int GetPar(int x){
if(Parent[x] == x) return x;
int pa = Parent[x];
Parent[x] = GetPar(Parent[x]);
//更新关系函数
Relation[x] = (Relation[x]+Relation[pa])%3;
return Parent[x];
}

bool Query(int x,int y,int d){
int a = GetPar(x);
int b = GetPar(y);
if(a ==b){
if(d == 1 && Relation[x] != Relation[y]) return false;
if(d == 2){
if(Relation[x] == 1 && Relation[y] != 0) return false;
if(Relation[x] == 2 && Relation[y] != 1) return false;
if(Relation[x] == 0 && Relation[y] != 2) return false;
}
return true;
}
/* 更新关系函数
x->y 代表y是父节点
0 :没关系
1 :吃掉y
2 :被y吃掉

用向量的进行巧解
*/
//x吃掉y =》 b为a的父节点
Parent[a] = b;
if(d == 2){
//有减法所以加三
Relation[a] = (Relation[y]+1-Relation[x] +3)%3;
}else{
Relation[a] =(Relation[y]-Relation[x]+3)%3;
}
return true;
}

int main(){
int x,y,d;
scanf("%d%d",&n,&k);
Init();
int ans = 0;
for(int i = 0;i<k;i++){
scanf("%d%d%d",&d,&x,&y);
if(x>n || y>n || (d==2 && x == y)){
ans++;
//continue忘了就是二倍
continue;
}
if(!Query( x,y,d)){
ans++;
}
}
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: