D07 最小生成树 Prim 算法
D07 最小生成树 Prim 算法——信息学奥赛算法_哔哩哔哩_bilibili
1. d[] 维护点到已选集合的最短距离
2. vis[] 维护点第1次出队
3. 优先队列 <d[],v> 维护最优点
4. 松弛:d[v]>w
5. 最优点第1次出队才有必要扩展
// Heap-Prim O((n+m)logn) #include<bits/stdc++.h> using namespace std; #define inf 1e9 const int N=5010; int n,m,a,b,c,ans,cnt; vector<pair<int,int>> e[N]; int d[N], vis[N]; bool prim(int s){ for(int i=0;i<=n;i++) d[i]=inf; d[s]=0; priority_queue<pair<int,int>> q; q.push({0,s}); while(q.size()){ int u=q.top().second; q.pop(); if(vis[u]) continue; vis[u]=1; //选u ans+=d[u]; cnt++; for(auto x:e[u]){ int v=x.first, w=x.second; if(d[v]>w){ //松弛 d[v]=w; q.push({-d[v],v}); } } } return cnt==n; } int main(){ cin>>n>>m; for(int i=0; i<m; i++){ cin>>a>>b>>c; e[a].push_back({b,c}); e[b].push_back({a,c}); } if(!prim(1)) puts("orz"); else printf("%d\n",ans); }
// Prim算法 O(n^2+m) #include<bits/stdc++.h> using namespace std; #define inf 1e9 #define N 5010 int n,m,a,b,c,ans,cnt; vector<pair<int,int>> e[N]; int d[N],vis[N]; bool prim(int s){ for(int i=0;i<=n;i++) d[i]=inf; d[s]=0; for(int i=1;i<=n;i++){ int u=0; for(int j=1;j<=n;j++) if(!vis[j]&&d[j]<d[u]) u=j; vis[u]=1; //选u ans+=d[u]; //树边和 if(d[u]!=inf) cnt++; //点数 for(auto x:e[u]){ int v=x.first,w=x.second; if(d[v]>w) d[v]=w; //松弛 } } return cnt==n; } int main(){ cin>>n>>m; for(int i=0; i<m; i++){ cin>>a>>b>>c; e[a].push_back({b,c}); e[b].push_back({a,c}); } if(!prim(1)) puts("orz"); else printf("%d\n",ans); }
浙公网安备 33010602011771号