您的位置:首页 > 其它

【解题报告】 POJ 1182 食物链 并查集的经典应用+相对位置

2012-08-02 22:38 501 查看
题目连接:POJ 1182

题目主要是得考虑找一个元素当这个集合的祖先,然后将其他两两动物之间的身份转变到对祖先的身份即可,这里用到一个向量转换相对身份,其实定义是可以改变的,一旦改变身份转换公式将改变。这道题做了我好长时间啊!!!

这里粘上一个人家的解题报告,给爱学习的你:关于食物链的详解

// POJ 1182 食物链 并查集
//测试数据(右缩进的为假话):
//5 10
//2 1 3
//1 2 1
//2 4 1
//2 3 4
//2 4 5
// 2 3 2
// 1 4 3
// 1 4 5
//1 1 5
// 1 3 5
//
//假设:
//   2    2                   --相对位置
// A -> B -> C -> A -> B -> C -> A
// 这样可以推出矛盾。
//
//定义为:
//         0——同类;
//         1——食物;吃父
//         2——天敌。被吃
//     4
//  ./   `\     //食物链
//5,2,1 -> 3
//动物编号:2->1->3->5  // father[x] = find(father[x]);          递归调用 压缩路径
//父节点: 1  3  5  5  // rank[x] = (rank[x] + rank[temp]) % 3  当前的相对的 + 父节点的相对的
//相对的: 0  1  2  0  // return father[x];
//           1  3
//           吃 被
//           3  5
//              吃

#include <stdio.h>
#include <string.h>

const int MAXA = 50010;
int father[MAXA],sp[MAXA]; // sp special value

void init(int n){
memset(sp,0,sizeof(sp));
for (int i = 1; i <= n; i++) // 初始每个动物都以自己为父节点,所以关系为0同类
father[i] = i;
}

int find (int x){

if(x == father[x]) return x;

int temp = father[x];
father[x] = find(father[x]); // 递归 更新他爹
sp[x] = (sp[x] + sp[temp]) % 3;	// 压缩更新他爹

return father[x]; // 只要返回它的爹 就可以了
}

void combination(int a,int b,int k){ // a b 关系为 k (this k is cut by 1) we should comb their root
int ra = father[a];
int rb = father[b];
father[ra] = rb; // make rb is the father of ra (把a的祖先接到b祖先上面)
sp[ra] = (k + sp[b] - sp[a] + 3) % 3;

}

int main(){
//	freopen("in.txt","r",stdin);
int N,K;
int D,X,Y;
int fsum = 0; // 假话的数量
scanf("%d%d",&N,&K); // 只有一组测试数据
init(N);
for (int i = 1 ; i <= K; i++){
scanf("%d%d%d",&D,&X,&Y);
if ( (D==2 && X==Y )||( X>N || Y>N ) ){ // the last two rules
//			printf("%d %d %d\n",D,X,Y);
fsum++;
}else{
int rx = find(X);
int ry = find(Y);
if (rx == ry){ // if they are in same set ,judge the relationship
if(sp[X] != (D - 1 + sp[Y] ) % 3){
//					printf("%d %d %d\n",D,X,Y);
fsum++;
}
}else{ // different set ,(combination)fusion
combination(X,Y,D-1);
}
}
}
printf("%d\n",fsum);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: