最小生成树
最小生成树是针对于无向图的,有向图没有这一概念,且这里边权值可以为负的
一般:稠密图——邻接矩阵 稀疏图——邻接表
Prim()
输出最小生成树的权重之和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| #include <bits/stdc++.h> using namespace std; const int N = 510, INF=0x3f3f3f3f; int n,m; int g[N][N]; int dist[N]; bool st[N]; int prim() { memset(dist,0x3f,sizeof(dist)); int res=0; for(int i=0;i<n;i++) { int t=-1; for(int j=1;j<=n;j++) if(!st[j] && (t==-1 || dist[t]>dist[j])) t=j; if(i&&dist[t]==INF) return INF; if(i) res+=dist[t]; for(int j=1;j<=n;j++) dist[j]=min(dist[j],g[t][j]); st[t]=true; } return res; } int main() { cin>>n>>m; memset(g,0x3f,sizeof(g)); while(m--) { int a,b,c; cin>>a>>b>>c; g[a][b]=g[b][a]=min(g[a][b],c); } int t=prim(); if(t==INF) cout<<"impossible"<<endl; else cout<<t<<endl; return 0; }
|
Kruskal()
- 所有边按权重从小到大排序 O(mlogm)
- 枚举每条边a,b 权重为c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| #include <bits/stdc++.h> using namespace std; const int N = 200010; int n,m; int p[N]; struct Edge { int a,b,w; bool operator< (const Edge &W)const { return w<W.w; } }edges[N]; int find(int x) { if(p[x]!=x) p[x]=find(p[x]); return p[x]; } int main() { cin>>n>>m; for(int i=0;i<m;i++) { int a,b,w; cin>>a>>b>>w; edges[i]={a,b,w}; } sort(edges,edges+m); for(int i=1;i<=n;i++) p[i]=i; int res=0,cnt=0; for(int i=0;i<m;i++) { int a=edges[i].a, b=edges[i].b, w=edges[i].w; a=find(a), b=find(b); if(a!=b) { p[a]=b; res+=w; cnt++; } } if(cnt<n-1) cout<<"impossible"<<endl; else cout<<res<<endl; return 0; }
|