最小生成树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 }