最小生成树prim算法

prim算法是一种用贪心思想的最小生成树算法。

初始先找到一个点,之后从这个点往下找,找一个权值最小的边及其到达的点,把这个点和第一个点当成一个生成树,再重复之前的步骤,最后找到n-1条边则停止。

Prim在稠密图中比Kruskal优,在稀疏图中比Kruskal劣。

例题:洛谷P2212 [USACO14MAR]Watering the Fields S

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<vector>
 7 #include<list>
 8 #include<queue>
 9 #include<stack>
10 #include<set>
11 using namespace std;
12 typedef long long ll;
13 ll n,c;
14 const int inf=0x3f3f3f3f;
15 ll dis[5001];
16 bool vis[5001];
17 ll x[100000],y[100000];
18 ll calc(ll u,ll v){
19     ll r=(x[u]-x[v])*(x[u]-x[v])+(y[u]-y[v])*(y[u]-y[v]);
20     if(r<c){
21         return inf;
22     }
23     return r;
24 }
25 void prim(){
26     for(int i=1;i<=n;i++){
27         dis[i]=inf;
28     }
29     dis[1]=0;
30     for(int i=1;i<=n;i++){
31         ll p=0;
32         for(int j=1;j<=n;j++){
33             if(!vis[j]){
34                 if(!p || dis[j]<dis[p]){
35                     p=j;
36                 }
37             }
38         }
39         vis[p]=1;
40         for(int i=1;i<=n;i++){
41             if(!vis[i]){
42                 dis[i]=min(dis[i],calc(p,i));
43             }
44         }
45     }
46     ll ans=0;
47     for(int i=2;i<=n;i++){
48         if(dis[i]==inf){
49             cout<<"-1"<<endl;
50             return;
51         }
52         ans+=dis[i];
53     }
54     cout<<ans;
55 } 
56 int main(){
57     cin>>n>>c;
58     for(int i=1;i<=n;i++){
59         cin>>x[i]>>y[i];
60     }
61     prim();
62     return 0;
63 }
原文地址:https://www.cnblogs.com/Raincym/p/13553256.html