首先說並查集有三種
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編號...