并查集
现在看自己之前的写的东西简直是傻逼至极;
果断删了,自己再yy一下有关并查集的模板;
首先是初始化(为什么要初始化呢?- -不初始化会死循环啊!还是不理解请看查询模板)
for(int i=1;i<=n;i++) fa[i]=i;
n为结点数;
合并:
int v=f[i].x; int u=f[i].y; if(find(v)!=find(u)) fa[find(v)]=find(u);
如果是裸的并查集,直接fa[find(v)]= find(u)就好了..以上那个多用在生成树中;
查询:(路径压缩)
int find(int x) if(fa[x]==x) return x; else return fa[x]=find(fa[x]);
之前在长乐集训的时候,有一题并查集加上路径压缩还是T了,正解是在合并的时候,还要按秩合并;
加入rank[N]来记录每个节点的秩(即树的高度),并按秩进行合并,可避免合并时的最糟糕情况,(树形为一条直线)
void UNION(int x, int y) { int f1 = find(x); int f2 = find(y); if (rank[f1] <= rank[f2]) { fa[f1] = f2; if (rank[f1] == rank[f2]) { rank[f2] ++; } } else { fa[f2] = f1; } };