一重扩展域并查集
/*
*扩展域并查集 二分图 容许问题
*/
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
static constexpr int N = 10,M = 20;
static int rep[N<<1|1]{0};
inline constexpr int __abs(const int x){return x<0?-x:x;}
int __find(int x){return (rep[x]<0)?x:(rep[x] = __find(rep[x]));}
inline void __union(int rx,int ry)
{
if(__abs(rep[rx])<=__abs(rep[ry]))
rep[rx] = ry,rep[ry]-=(int)(rep[rx] == rep[ry]);
else rep[ry] = rx;
}
_Bool SOLVE(void)
{
memset(rep,-1,sizeof rep);
int i,x,y,rx,ry;
for(i = 0;i++<M;)
{
scanf("%d%d",&x,&y);
if((rx = __find(x)) == (ry = __find(y)))return 0;
__union(rx,y+N);__union(x+N,ry);
}
return 1;
}
权值并查集
/*
*加权并查集
*/
#include <vector>
static constexpr int N = 10;
static std::vector<int> par(N+1,0),val(N+1,0);
static int w[N][N]{{}};
static void init(void){int i = 0;for(auto&e:par)e = ++i;}
static int _Find(int f)
{
if(f == par[f])return f;
int r = _Find(par[f]);val[f]+=val[par[f]];
return (par[f] = r);
}
static void _Mrg(int x,int y)
{
int rx{0},ry{0};
if((rx = _Find(x)) == (ry = _Find(y)))return;
par[rx] = ry;
val[rx] = -val[x]+val[y]+w[x][y];
}