最小生成树(prim and kruskal)
最小生成树算法
比较经典的是这两种 prim kruskal
思想都是贪心的思想
然而我只会一种...kruskal
这里用到了并查集check关系
先将边权从小到大排序,每次选择没有选择的边中的最小边权,check一下是否会形成环,如果形成环就不选择 否则就选择这条边,就这么做下去...
用邻接表结构来记录边的两个顶点和边权
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 using namespace std; 5 typedef long long ll; 6 const int maxn=150005; 7 struct node{ 8 int u, v, cost; 9 }G[maxn]; 10 int a[maxn]; 11 void init(int N){ 12 for(int i=0; i<N; i++){ 13 a[i]=i; 14 } 15 } 16 bool same(int x, int y){ 17 return a[x]==a[y]; 18 } 19 int Find(int x){ 20 return a[x]==x?x:(a[x]=Find(a[x])); 21 } 22 void Merge(int x, int y){ 23 x=Find(x); 24 y=Find(y); 25 a[x]=y; 26 } 27 bool cmp(node a, node b){ 28 return a.cost<b.cost; 29 } 30 31 int main(){ 32 int n, m; 33 cin>>n>>m; 34 init(n); 35 for(int i=0; i<m; i++){ 36 cin>>G[i].u>>G[i].v>>G[i].cost; 37 } 38 sort(G, G+m, cmp); 39 ll ans=0; 40 for(int i=0; i<m; i++){ 41 int U=G[i].u, V=G[i].v; 42 U=Find(U), V=Find(V); 43 if(!same(U, V)){ 44 Merge(U, V); 45 ans+=G[i].cost; 46 } 47 } 48 cout<<ans<<endl; 49 return 0; 50 }