两种方法:prim:和克鲁斯卡尔,推荐后者。
prim:
(其实和Dijkstra是一个东西,只有几处代码不同)
#include<cstdio> #include<cstring> using namespace std; int g[310][310]; int n,m,a,b,c,minn[310],mmax=-1; bool u[310]; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;++i){ scanf("%d%d%d",&a,&b,&c); g[a][b]=c; g[b][a]=c; } memset(minn,0x7f,sizeof(minn)); minn[1]=0; memset(u,1,sizeof(u)); for(int i=1;i<=n;++i){ int k=0; for(int j=1;j<=n;j++) if(u[j]&&(minn[j]<minn[k])) k=j; u[k]=0; for(int j=1;j<=n;j++) if(u[j] && g[k][j]!=0 && g[k][j]<minn[j]) minn[j]=g[k][j]; } for(int i=1;i<=n;++i){ if(minn[i]>mmax) mmax=minn[i]; } printf("%d %d",n-1,mmax); return 0; }
克鲁斯卡尔:
用了并查集的思想,比较推荐
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; int m, n, u, v, c, maxn, k; int fa[301]; int find(int x) { if(fa[x]!=x) fa[x]=find(fa[x]); return fa[x]; } void unionn(int x,int y) { int fx = find(x); int fy = find(y); if (fx != fy) fa[fx]=fy; } struct Node { int x, y, v; bool operator < (const Node &b) const { return v<b.v; } }a[51000]; int main() { cin >> n >> m; for (int i=1; i<=m; i++) { cin >> u >> v >> c; a[i]=(Node){u, v, c}; } for (int i=1; i<=n; i++) fa[i]=i; sort(a+1,a+m+1); for (int i=1; i<=m; i++) { if (find(fa[a[i].x]) != find(fa[a[i].y])) { unionn(a[i].x, a[i].y); maxn = a[i].v; k++; } if (k == n-1) break; } cout<< n-1 << " " <<maxn; return 0; }
未完成的Prim堆优化
#include <iostream> #include <cstdio> #include <queue> #define oo 0x7FFFFFFF using namespace std; int n, m, tot, MST; int d[5001]; int head[5010]; bool vis[5010]; struct rqy { int x; bool operator < (const rqy &a) const { return d[a.x]<d[x]; } }; priority_queue <rqy> q; struct Node { int data; int js; int plink; Node() { data=plink=js=0; } }node[20010]; void link(int x,int y, int num) { node[++tot].data=num; node[tot].plink=head[x]; node[tot].js=y; head[x]=tot; return ; } int main() { cin >> n >> m; d[1] = oo; head[1] = 0; vis[1]=1; for (int i = 2; i <= n; ++i) { d[i]=oo; head[i]=0; q.push((rqy){i}); } vis[1]=1; for (int i=1; i<=m; i++) { int u, v, num; cin>>u>>v>>num; link(u, v, num); link(v, u, num); } for (int i=head[1]; i; i=node[i].plink) d[node[i].js]=node[i].data; for (int i=1; i<n; i++) { int u=q.top().x; q.pop(); MST+=d[u]; vis[u]=1; for (int j=head[u]; j; j=node[j].plink) { int v=node[j].js; if(!vis[v] && node[j].data < d[v]) d[v]=node[j].data; } } cout << MST; return 0; }