题目描述:
N个点M条边的有向连通图,每条边有一个权值,求该图的最小生成树。
第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)
输出最小生成树的所有边的权值之和。
9 14
1 2 4
2 3 8
3 4 7
4 5 9
5 6 10
6 7 2
7 8 1
8 9 7
2 8 11
3 9 2
7 9 6
3 6 4
4 6 14
1 8 8
37 题目分析: Prim算法,每次选择最短的线段,并将产生最短线段的点,拉入最小生成树序列,直到n个点全部进入序列。 AC代码:/** *1、最小生成树Prim算法(2015.1.1) *2、Kruskal算法 */ #include<iostream> #include<cstdio> #include<map> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<vector> #include<stack> #include<cstdlib> #include<cctype> #include<cstring> #include<cmath> using namespace std; const int inf=0x3f3f3f3f; int G[1001][1001];//邻接矩阵 int vis[1001],lowc[1001]; int prim(int G[][1001],int n){ int i,j,p,minc,res=0; memset(vis,0,sizeof(vis)); vis[1]=1;//从1开始访问 for(i=2;i<=n;i++) lowc[i]=G[1][i]; for(i=2;i<=n;i++){ minc=inf; p=-1; for(j=1;j<=n;j++){ if(vis[j]==0&&lowc[j]<minc){ minc=lowc[j]; p=j; } } //cout<<minc<<endl; if(inf==minc) return -1;//原图不联通 res+=minc; vis[p]=1; for(j=1;j<=n;j++){//更新lowc[] if(vis[j]==0&&lowc[j]>G[p][j]){ lowc[j]=G[p][j]; } } } return res; } int main() { int n,m; while(cin>>n>>m){ int x,y,w; memset(G,inf,sizeof(G));//首先记录所有边的权为inf for(int i=1;i<=m;i++){ cin>>x>>y>>w; G[x][y]=G[y][x]=w; //cout<<G[x][y]<<endl; } //int res=prim(n); cout<<prim(G,n)<<endl; } return 0; }
原文地址:http://blog.csdn.net/fool_ran/article/details/42616131