javarscript中的var作用
阿新 • • 發佈:2021-01-01
力扣547
並查集主要用於解決一些元素分組的問題。
它管理一系列不相交的集合,並支援兩種操作:
合併(Union):把兩個不相交的集合合併為一個集合。
查詢(Find):查詢兩個元素是否在同一個集合中。
親戚問題
題目背景
若某個家族人員過於龐大,要判斷兩個是否是親戚,確實還很不容易,現在給出某個親戚關係圖,求任意給出的兩個人是否具有親戚關係。
題目描述
規定:x和y是親戚,y和z是親戚,那麼x和z也是親戚。如果x,y是親戚,那麼x的親戚都是y的親戚,y的親戚也都是x的親戚。
輸入格式
第一行:三個整數n,m,p,(n<=5000,m<=5000,p<=5000),分別表示有n個人,m個親戚關係,詢問p對親戚關係。以下m行:每行兩個數Mi,Mj,1<=Mi,Mj<=N,表示Mi和Mj具有親戚關係。
接下來p行:每行兩個數Pi,Pj,詢問Pi和Pj是否具有親戚關係。
輸出格式
P行,每行一個’Yes’或’No’。表示第i個詢問的答案為“具有”或“不具有”親戚關係。
模板
/**
* 並查集演算法
* 我們設定樹的每個節點有一個指標指向其父節點,如果是根節點的話,這個指標指向自己
*/
public class UnionFind {
private int[] p;
private int[] size;
private int count;
public static void main(String[] args) {
}
public UnionFind(int n) {
p = new int[n];
size = new int[n];
for(int i=0;i<n;i++) {
p[i]=i;
size[i]=1;
}
count = n;
}
public void union(int p, int q) {
if(p==q)return;
int x = find(p);
int y = find(q);
/**
//容易導致樹的不平衡
if(x!=y) {
this.p[x] = y;
count--;
}
*/
//小樹接到大樹下面,較平衡
//通過比較樹的重量,就可以保證樹的生長相對平衡,樹的高度大致在logN這個數量級,極大提升執行效率。
if(size[x]>size[y]) {
this.p[y]=x;
size[x]+=size[y];
}else {
this.p[x]=y;
size[y]+=size[x];
}
count--;
}
/**
* find主要功能就是從某個節點向上遍歷到樹根,其時間複雜度就是樹的高度。
* 我們可能習慣性地認為樹的高度就是logN,但這並不一定。
* logN的高度只存在於平衡二叉樹,對於一般的樹可能出現極端不平衡的情況,使得「樹」幾乎退化成「連結串列」,
* 樹的高度最壞情況下可能變成N。
*/
public int find(int x) {
/**
while(p[x]!=x) {
x=p[x];
}
*/
//我們能不能進一步壓縮每棵樹的高度,使樹高始終保持為常數?
while(p[x]!=x) {
p[x]=p[p[x]];
x=p[x];
}
return x;
}
public boolean connected(int p, int q) {
return p==q?true:find(p)==find(q);
}
public int count() {
return this.count;
}
}