并查集
//初始化 int father[N]; for(int i=1; i<=N; i++){ father[i] = i; //令father[i]为1也可 } //查找 int findFather(int x){ //由于x在下面的while中会变成根结点,因此先把原来的x先保存下 int a = x; while(x != father[x]){ //如果不是根结点,继续循环 x = father[x]; //获得自己的父亲结点 } //路径压缩(可不写)把路径上的所有结点的father都改成根结点 while(a != father[a]){ int z = a; a = father[a]; father[z] = x; } return x; } //较小时间复杂度的查找(路径压缩) int findFather(int v){ if(v == father[v]) return v; //找到根结点 else{ int F = findFather(father[v]); //递归寻找father[v]的根结点 father[v] = F; //将根结点F赋给father[v] return F; //返回根结点 } } //合并 void Union(int a, int b){ int faA = findFather(a); //查找a的根结点,记为faA int faB = findFather(b); //查找b的根结点,记为faB if(faA != faB){ //如果不属于同一个集合 father[faA] = faB; //合并 } }