並查集解題思路

KS_Fszha發表於2024-04-06

概述

並查集主要是解決以下幾種問題的:

  1. 各節點之間的關係
  2. 某節點和它祖先之間的關係

種類

  1. 樸素並查集,一個集合的資訊可以儲存在它的祖先節點上。
  2. 帶權並查集,維護的是某節點與它祖先的關係
  3. 擴充套件域並查集(種類並查集),本質是多開幾倍空間的樸素並查集,維護的是各個陣營之間的關係,且幾個域裡具有對稱性。形式化而言,可以把每個域看作一個平行時空,當朋友域裡的我和朋友域裡的他是朋友時,我和他是朋友;當朋友域裡的我和敵人域裡的他是朋友時,我和他是敵人。

模板

樸素並查集模板

點選檢視程式碼
int findf(int x)
{
    if(f[x]!=x)f[x]=findf(f[x]);
    return f[x];
}

帶權並查集模板

點選檢視程式碼
int findf(int x)
{
	if(f[x]==x)return x;
	int orif=f[x];
	f[x]=findf(f[x]);
	dis[x]+=dis[orif];
	return f[x];
}

種類並查集模板

樸素並查集上多開幾倍空間。

求最大連通塊點數

樸素並查集,把該連通塊資訊算在祖先節點上,combine 時就傳遞祖先節點的資訊。

求連通塊數量

祖先節點的個數就是連通塊數量,因此遍歷每一個點,如果 findf(i)==inum++

套路

  1. 幾個點之間可以任意交換,則他們是一個集合,常用於序列上的並查集問題。交換
  2. 帶權並查集的權值取模,可以當成種類並查集來用。食物鏈
  3. 建立虛點,來實現兩個集合合併時,不影響兩個集合原來各自的操作,且後續共享操作的功能。網路分析
  4. 破壞兩個節點間的關係,反向合併集合,從最後一次破壞開始,往前合併破壞的節點。星球大戰
  5. 判斷兩種說法是否矛盾,把相同的說法加入同一個並查集裡;可以在一開始時就判斷矛盾,也可以在最後才判斷。程式自動分析
  6. 判斷圖的連通性,如 Kruskal 演算法。
  7. 最少的任意位置的交換次數,把要交換的東西合併成一個集合,交換次數即為 \(size-1\)情侶牽手
  8. 判斷是否有環的存在。
  9. 超級源點,這個超級源點既可以看作是把整個集合賦某個特定的值,也可以看作是給一些滿足要求的節點連邊。三值邏輯被圍繞的區域

相關文章