Prim——最小生成树
Description
给你一个具有n个点,m条边的无向连通图,求其最小生成树的权值和。
Input
第一行两个整数n(1<=n<=300)和m,分别表示图的顶点数和边数。
接下来m行是每行三个整数u, v, c,表示结点u和v之间有边相连,权值为c(1≤c≤10000)。
Output
输出文件仅一个整数为最小生成树的权值和。
Sample Input
3 3
1 2 5
2 3 3
1 3 1
Sample Output
4
注意prim的状态转移方程
Prim:d[to]=min(d[to], a[o].value );
Dijkstra:d[to]=min(d[to], a[o].value+d[k] );
区别:
Prim: d[i]表示i节点到最小生成树的集合的最短距离
Dijkstra: d[i]表示i节点到单源点的最短距离
1 #include<bits/stdc++.h> 2 #define inf 0x7fffffff 3 using namespace std; 4 int n,m; 5 struct eg 6 { 7 int next,to,value; 8 }a[100000]; 9 void fin(int &x) 10 { 11 scanf("%d",&x); 12 } 13 int h[100000]; 14 int cnt; 15 int d[100000]; 16 int vis[100000]; 17 int ans; 18 void Union(int x,int y,int z) 19 { 20 cnt++; 21 a[cnt].next=h[x]; 22 a[cnt].to=y; 23 a[cnt].value=z; 24 h[x]=cnt; 25 } 26 int main() 27 { 28 fin(n); 29 fin(m); 30 for(int i=1;i<=m;i++) 31 { 32 int x,y,z; 33 fin(x); 34 fin(y); 35 fin(z); 36 Union(x,y,z); 37 Union(y,x,z); 38 } 39 fill(d+1,d+n+1,inf); 40 d[1]=0; 41 for(int i=1;i<=n;i++) 42 { 43 int minn=0x7fffffff; 44 int k; 45 for(int o=1;o<=n;o++)if(d[o]<minn&&vis[o]==0)minn=d[o],k=o; 46 vis[k]=1; 47 ans+=d[k]; 48 for(int o=h[k];o;o=a[o].next) 49 { 50 int to=a[o].to; 51 if(vis[to]==0) 52 { 53 d[to]=min(d[to],a[o].value); 54 } 55 } 56 } 57 cout<<ans; 58 }