並查集(全解)

2022-06-30 05:24:10 字數 2550 閱讀 2615

首先說並查集有三種

1、第一種是最簡單的,沒有權值

2、第二種是帶權值的並查集

3、第三種是種類並查集(後面以食物鏈這道題來講解)

每一種都是有模板的,要盡可能理解後才能長時間記憶

一、(first of all)

所有並查集由三部分組成-------主函式、尋找根節點函式(finds)、合併根節點函式(join)、以上三種只是在這三各部分中有所不同

finds函式

int finds(int x)

return x;

}join函式:

void join(int x,int y,int z)

二、例題:

finds函式

int finds(int x)

return x;

}join函式:

這一點就要涉及權值問題,在權值問題上面三角形是用來判斷這一句話正確還是錯誤,四邊形是用來判斷在合併根節點時根節點之間的權值問題

1、三角形是當要合併的兩個點的根節點一樣的時候用來判斷正確與否(根節點一樣,就不需要合併,要檢查之前的操作是否與現在的衝突)

此時的他們滿足這個情況

我們就是要判斷這個現在題中給出的x到y之間的權值,與之前給出的x到其根節點與y到其根節點而推出來的x到y之間的距離比較,不相等的話,那麼這句話就錯了。。。

比如2--->1之間的距離是4,3--->1之間的距離是4,那麼2--->3之間的距離不就是0,(這裡舉的是事物物件,不要和數軸聯絡)

四角形就是用來為連線後的根節點賦值

此時,你已經知道x,y到其根節點之間的距離,題中一旦要讓x與y合併,此時三條向量邊,你就知道了三條,那不就可以求出來w[x]的值

此時你就用向量加減,如果方向相反就減去它

注意:你不能讓fy指向fx,有的題目是不允許的,就比如給你區間【1,2】,和區間【3,4】的長度1,1,接著題目中再給出2到3的距離1,

按照fy指向fx則有:w[fy]=w[x]-z-w[y]就是乙個負值,所以盡量都用fx---->fy

void join(int x,int y,int z)

else

}最後這道題要注意一點,你往join函式裡面傳值的時候,要將傳之前y對應的那個變數值加一,要不然他們之間不會連起來

三、例題:食物鏈 

finds函式:

此時假設

0:同類

1:父吃子

2:子吃父

根據那個四邊形w[fx]=3-w[x]+z+w[y]       //3-w[x]的原因是w[x]箭頭向上,要反向就要減去他,但是害怕減去之後總和為負值,所以就用3減去它

因為我們用的是fx--->fy,所以此時x指向的y也是父類,當輸入的z為2的時候意思是x吃y,x吃y是子吃父,所以此時這個z不變

當輸入z為1的時候,是同類的意思,而我們規定同類是0,所以我們要讓z減去1

int finds(int x)

return x;

}join函式:

void join(int x,int y,int z)

if(z==2 && (w[y]+2)%3!=w[x])

}else

}這個時候我們規定

0:同類

2:父吃子

1:子吃父

所以當z為2的時候減去一就符合,所以不用,將z等於1和z等於2分開來寫

void join(int x,int y,int z)

if(z==2 && (w[y]+1)%3!=w[x])

}else

}下面依次是兩種方法的**

1、#include

#include

int v[50005],w[50005],ans=0;

int finds(int x)

return x;

}void join(int x,int y,int z)

if(z==2 && (w[y]+2)%3!=w[x])

}else

}int main()

while(s--)

if(d==2 && f==g)

join(f,g,d);

}printf("%d\n",ans);

return 0;}2、

#include

#include

int v[50005],w[50005],ans=0;

int finds(int x)

return x;

}void join(int x,int y,int z)

if(z==2 && (w[y]+1)%3!=w[x])

}else

}int main()

while(s--)

if(d==2 && f==g)

join(f,g,d);

}printf("%d\n",ans);

return 0;

}

並查集 並查集

本文參考了 挑戰程式設計競賽 和jennica的github題解 陣列版 int parent max n int rank max n void init int n int find int x else void union int x,int y else 結構體版 struct node ...

並查集入門(普通並查集 帶刪除並查集 關係並查集)

什麼是並查集?通俗易懂的並查集詳解 普通並查集 基礎並查集 例題 題解 how many tables problem description lh boy無聊的時候很喜歡數螞蟻,而且,還給每乙隻小螞蟻編號,通過他長期的觀察和記錄,發現編號為i的螞蟻會和編號為j的螞蟻在一起。現在問題來了,他現在只有...

並查集,帶權並查集

題意 ignatius過生日,客人來到,他想知道他需要準備多少張桌子。然而一張桌子上面只能坐上相互熟悉的人,其中熟悉可定義成為a與b認識,b與c認識,我們就說a,b,c相互熟悉 例如a與b熟悉and b與c熟悉,d與e熟悉,此時至少需要兩張桌子。輸入 t表示樣例個數,n表示朋友個數,朋友從1到n編號...