Kruscal&它的好朋友並查集
阿新 • • 發佈:2018-12-13
……我覺得我需要寫一下並查集……畢竟我這麼菜……不寫篇部落格過幾天我都不知道自己學過 找爸爸 並查集了
但我這麼菜,我也寫不出太多東西……那就讓這倆一起吧QwQ 反正kruscal也要用並查集的QwQ
並查集
並查集,俗稱找爸爸(霧),就是多個集合之間的查詢&合併,具體操作包括:查詢某兩點是否在同一集合,合併某兩點所在集合,以及一些鬼畜的操作
先貼程式碼,再說思想
int find(int x)
{
if (f[x]!=x)
f[x]=find(f[x]);
return f[x];
}
上面的是並查集最最最核心的操作:找爸爸
其實原理非常的簡單:如果x不是自己的爸爸,那麼x一定不是根節點,於是我們再去找x的爸爸的爸爸,直到x的爸爸的爸爸的爸爸的……p終於是自己的爸爸了,於是x和他的爸爸們都找到了他們的爸爸,也都直接把他們的爸爸變成了p,這其實也就是路徑壓縮
找到了爸爸,接下來就是查詢操作
原理更簡單了,(程式碼我都不想放),分別查詢兩個節點的爸爸,看看這兩個點的爸爸是不是一個爸爸
最後就是合併操作了
更簡單了,把一個點的爸爸變成另一個點的爸爸的兒子
#include<bits/stdc++.h> using namespace std; int f[10010]; int fa(int x) { if (f[x]==x) return x; return f[x]=fa(f[x]); } int main() { int n,m; cin>>n>>m; for (int i=1;i<=n;i++) f[i]=i; for (int i=1;i<=m;i++) { int z,a,b; cin>>z>>a>>b; if (z==1) f[fa(a)]=fa(b); if (z==2) if (fa(a)==fa(b)) cout<<"Y"<<endl; else cout<<"N"<<endl; } return 0; }
咳咳咳接下來是kruscal
Kruscal
一個簡陋的、沒什麼用的、目錄
- 演算法思想
- 直接上程式碼
演算法思想
從小到大遍歷每條邊,如果這條邊的兩個端點不在一個集合裡,就合併他們,直到所有點都被連起來
程式碼實現
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<ctime> #include<algorithm> #include<queue> #include<cstdlib> using namespace std; int jishuqi,f1,f2,f[10100]; struct edge { int a,b,val; }e[10010]; int find(int x) { if (f[x]!=x) f[x]=find(f[x]); return f[x]; } bool cmp(edge a,edge b) { return a.val<b.val; } int main() { int n,m; cin>>n>>m; for (int i=1;i<=n;i++) f[i]=i; for (int i=1;i<=m;i++) cin>>e[i].a>>e[i].b>>e[i].val; sort(e+1,e+m+1,cmp); for (int i=1;i<=m;i++) { f1=find(e[i].a); f2=find(e[i].b); if (f1==f2) continue; else { f[f1]=f[f2]; jishuqi=jishuqi+e[i].val; } } cout<<jishuqi; return 0; }
【完結撒花✿✿ヽ(°▽°)ノ✿】【這次好草率的說】