POJ1182

来源:互联网 发布:android 7.0 数据库 编辑:程序博客网 时间:2024/06/12 01:38

链接:http://poj.org/problem?id=1182

定义一种关系R(x,y),x > y 时 R(x,y) = 2;x = y 时 R(x,y)= 1;x < y 时 R(x,y) = 0

则R(x,y)有如下运算法则:
R(x,y) = (R(x,u) - R(y,u) + 4) % 3

R(x,y) = (R(x,u) + R(u,y) + 2) % 3

...

用并查集维持这种关系

/**************************************************************  作者:陈新  邮箱:cx2pirate@gmail.com  用途:poj1182  时间:2014年 4月12日 15:00  测试:12745220Will49441182Accepted548K282MSC++967B2014-04-12 14:58:49 *************************************************************/ #include <stdio.h>#define MAX_N 50005int pre[MAX_N];//并查集int rel[MAX_N];//与根节点关系void init();int find(int u);void unite(int r,int u,int v);int main(){int m,n;//while(scanf("%d%d",&m,&n) != EOF){    我去!。。。。scanf("%d%d",&m,&n);int r,u,v,sum = 0;init();for(int i = 0;i < n;i++){scanf("%d%d%d",&r,&u,&v);if(u > m || v > m || (r == 2 && u == v)){sum++;continue;}if(find(u) == find(v)){if((rel[u] - rel[v] + 4) % 3 != r){sum++;}}else{unite(r,u,v);}}printf("%d\n",sum);//}}void init(){for(int i = 0;i < MAX_N;i++){pre[i] = i;rel[i] = 1;}}int find(int u){if(pre[u] == u){return u;}int t = find(pre[u]);rel[u] = (rel[u] + rel[pre[u]] + 2) % 3;pre[u] = t;return pre[u];}void unite(int r,int u,int v){int pu = find(u);int pv = find(v);pre[pu] = pv;rel[pu] = (r + rel[v] - rel[u] + 3) % 3;}


0 0
原创粉丝点击