首先定義演算法的api
方法作用
uf(int n)
初始化觸點及其他資料
int find(int p)
返回p所在連通分量的識別符號
int union(int p,int q)
在p和q之間新增一條線
int count ()
返回連通分量的數量
boolean connected(int p,int q)
如果p和q之間有一條線就返回true
1.好了,api已經定義好了,下面可以實現這個api,下面是第乙個版本。實現思想是利用判斷id[q]和id[p]是否相等來判斷它們是否在同乙個連通分量中。它的缺點是一般無法處理大規模問題,因為每次呼叫它都需要掃瞄一次陣列,對於最終值得到少量連通分量的問題執行時間是平方級別的。
public
class
unionfind
public
intfind(int p)
public
intgetcount()
public
boolean
connected(int p,int q)
public
void
union(int p, int q)
count--;//合併之後因為連通分支數少一,所以減一
}}
2.上面的那個演算法不適用與大資料處理,原因是對於最終得到的連通分量問題的執行時間是平方級別的。下面的這個演算法它優化了union()方法,並修改了find()方法以配合union()方法的使用。它的設計思想是定義與之前不同的資料結構,每個觸點所對應的id元素都是同乙個分量中的另乙個觸點的名稱(也有可能是它自己)——我們將這種聯絡稱為鏈結。每個連通分量都有乙個根觸點。根觸點的特點是id[i] = i。這種資料結構使得union()在最壞情況下得到的結果是平方級別的,一般情況下是線性對數級別的。而find()方法的執行時間取決於數的高度。
public
class
quickunion
public
intfind(int p)
public
intgetcount()
public
boolean
connected(int p,int q)
public
void
union(int p, int q)
}
3.下面是第三種方法實現,它進一步優化了第二種實現,使得在最壞情況下union()也保持線性對數級別的執行時間。設計思想是在union()中不是隨意將一棵樹鏈結到另一棵樹中,而是通過新增乙個陣列來記錄每顆數的大小,將較小的一顆鏈結到較大的一顆樹上。我們將它稱為加權quick-union演算法。
public
class
weightedquickunion
}public
intgetcount()
public
boolean
connected(int p,int q)
private
intfind(int p)
public
void
union(int p,int q)
else
count --;
}}
總結:由上面的演算法優化可以知道,演算法優化不是一步到位的,它中間需要乙個過程 連通性問題
1 伺服器可以ping通客戶端,說明伺服器和客戶端之間的鏈路是通的。客戶端不能ping通伺服器,很可能是防火牆的原因,包括伺服器本身自帶的防火牆和伺服器與交換機之間的cisco asa 5505防火牆。防火牆的訪問規則中清除禁止ping入之類的規則,或者清除拒絕接收icmp包的規則。2 ping不通...
SOJ 連通性問題
description 關係r具有對稱性和傳遞性。數對p q表示prq,p和q是0或自然數,p不等於q。要求寫乙個程式將數對序列進行過濾,如果乙個數對可以通過前面數對的傳遞性得到,則將其濾去。例如 輸入 輸出 連通性 3 4 3 4 4 9 4 9 8 0 8 0 2 3 2 3 5 6 5 6 2...
《演算法》筆記 2 動態連通性問題
在基礎部分的最後一節,作者用乙個現實中應用非常廣泛的案例,說明以下幾點 動態連通性問題的輸入是一列整數對,其中的每個整數都表示乙個某種型別的物件,一對整數對p q可以理解為 p和q是相連的 相連是一種等價關係,其具有 程式的目標是過濾掉序列中無意義的整數對,當程式從輸入中讀取了整數對pq時,如果已知...