Prim——最小生成树

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 }

猜你喜欢

转载自www.cnblogs.com/boruto/p/9556449.html