1212 无向图最小生成树基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树。Input第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 <= N <= 1000, 1 <= M <= 50000)第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N,1 <= W <= 10000)Output输出最小生成树的所有边的权值之和。Input示例9 141 2 42 3 83 4 74 5 95 6 106 7 27 8 18 9 72 8 113 9 27 9 63 6 44 6 141 8 8Output示例37//用普里姆算法(贪心策略)#include<iostream>using namespace std;const static int WHITE=0;const static int GRAY=1;const static int BLACK=2;const static int MAX=10000;const static int INFTY=(1<<21);int m,n;int color[MAX],d[MAX],p[MAX],M[MAX][MAX];//p[n]是父结点数组,d[n]记录权值最小边的权值int PRim(){ for(int i=1;i<=n;i++)//初始化 { color[i]=WHITE; p[i]=-1; d[i]=INFTY; } d[1]=0; while(1) { int minv=INFTY,u=-1; for(int i=1;i<=n;i++) { if(color[i]!=BLACK&&d[i]<minv)//未被访问 { minv=d[i];//选出最小的边 u=i; } } if(u==-1) break; color[u]=BLACK; for(int v=1;v<=n;v++) { if(color[v]!=BLACK&&M[u][v]!=0)//未被访问,且相连 { if(d[v]>M[u][v])//更新 { d[v]=M[u][v]; p[v]=u; color[v]=GRAY; } } } } int sum=0; for(int i=1;i<=n;i++) { sum+=d[i]; } return sum;}int main(){ int a,b,l; cin>>n>>m; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { M[i][j]=0; } } for(int i=1;i<=m;i++) { cin>>a>>b>>l; M[a][b]=M[b][a]=l; } cout<<prim()<<endl; return 0;}
新闻热点
疑难解答