并查集

//带路径压缩的并查集,用于动态维护查询等价类

//图论算法中动态判点集连通常用

//维护和查询复杂度略大于O(1)

//集合元素取值1..MAXN-1(注意0不能用!),默认不等价

#include <string.h>

#define MAXN 100000

#define _ufind_run(x) for(;p[t=x];x=p[x],p[t]=(p[x]?p[x]:x))

#define _run_both _ufind_run(i);_ufind_run(j)

struct ufind{

int p[MAXN],t;

void init(){memset(p,0,sizeof(p));}

void set_friend(int i,int j){_run_both;p[i]=(i==j?0:j);}

int is_friend(int i,int j){_run_both;return i==j&&i;}

};

//带路径压缩的并查集扩展形式

//用于动态维护查询friend-enemy型等价类

//维护和查询复杂度略大于O(1)

//集合元素取值1..MAXN-1(注意0不能用!),默认无关

#include <string.h>

#define MAXN 100000

#define sig(x) ((x)>0?1:-1)

#define abs(x) ((x)>0?(x):-(x))

#define _ufind_run(x) for(;p[t=abs(x)];x=sig(x)*p[abs(x)],p[t]=sig(p[t])*(p[abs(x)]?p[abs(x)]:abs(p[t])))

#define _run_both _ufind_run(i);_ufind_run(j)

#define _set_side(x) p[abs(i)]=sig(i)*(abs(i)==abs(j)?0:(x)*j)

#define _judge_side(x) (i==(x)*j&&i)

struct ufind{

int p[MAXN],t;

void init(){memset(p,0,sizeof(p));}

int set_friend(int i,int j){_run_both;_set_side(1);return !_judge_side(-1);}

int set_enemy(int i,int j){_run_both;_set_side(-1);return !_judge_side(1);}

int is_friend(int i,int j){_run_both;return _judge_side(1);}

int is_enemy(int i,int j){_run_both;return _judge_side(-1);}

};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值