700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 最小生成树 - Prim算法

最小生成树 - Prim算法

时间:2021-10-10 10:25:36

相关推荐

最小生成树 - Prim算法

最小生成树 - Prim算法

思路:

采用贪心策略,每次选取连通块外延的最短边和对应的点放入连通块,再更新新的连通块外延的边。连通部分逐渐扩大,最后将整个图连通起来,并且边长之和最小

时间复杂度:O( n ^ 2 ),应用于稠密图

伪代码 / 模板:

int prim(){memset(dist,INF,sizeof dist); //dist[i]表示i节点到连通块的最短路径//st[i]标记i节点是否在连通块内int ans=0;for(int i=0;i<n;i++){int hp=-1;for(int j=1;j<=n;j++){//寻找到连通块最近的点if(!st[j]&&(hp==-1||dist[hp]>dist[j]))hp=j;}if(i&&dist[hp]==INF) //不连通return INF;if(i)ans+=dist[hp];st[hp]=true;for(int j=1;j<=n;j++){//更新外延边dist[j]=min(dist[j],mp[hp][j]);}}return ans; //最小边长和}

模板题:AcWing858. Prim算法求最小生成树

题面:(传送门)

思路:

模板题还需要思路?见前文模板代码注释。

AC代码:

#include<iostream>#include<cstring>using namespace std;const int N=505;const int INF=0x3f3f3f3f;int n,m;int mp[N][N];int dist[N];bool st[N];int prim(){memset(dist,INF,sizeof dist);int ans=0;for(int i=0;i<n;i++){int hp=-1;for(int j=1;j<=n;j++){if(!st[j]&&(hp==-1||dist[hp]>dist[j]))hp=j;}if(i&&dist[hp]==INF)return INF;if(i)ans+=dist[hp];st[hp]=true;for(int j=1;j<=n;j++){dist[j]=min(dist[j],mp[hp][j]);}}return ans;}int main(){//freopen("D:\\in.txt","r",stdin);cin>>n>>m;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(i==j)mp[i][j]=1;elsemp[i][j]=INF;}}int u,v,w;for(int i=0;i<m;i++){scanf("%d%d%d",&u,&v,&w);mp[u][v]=mp[v][u]=min(mp[u][v],w);}int ans=prim();if(ans==INF)cout<<"impossible"<<endl;elsecout<<ans<<endl;return 0;}

应用题:HDU_7058. Ink on paper

题面:(传送门)

思路:

因为任意两滴墨点只要时间足够都会联通

两个墨点双向奔赴即速度为 1 c m / s 1cm/s 1cm/s

墨点间的距离为 ( x 1 − x 2 ) ∗ ( x 1 − x 2 ) + ( y 1 − y 2 ) ∗ ( y 1 − y 2 ) \sqrt{(x_{1}-x_{2})*(x_{1}-x_{2})+(y_{1}-y_{2})*(y_{1}-y_{2})} (x1​−x2​)∗(x1​−x2​)+(y1​−y2​)∗(y1​−y2​) ​

但答案要求输出最短时间的平方

综上,任意两墨点联通的时间的平方即 答案 为 ( x 1 − x 2 ) ∗ ( x 1 − x 2 ) + ( y 1 − y 2 ) ∗ ( y 1 − y 2 ) (x_{1}-x_{2})*(x_{1}-x_{2})+(y_{1}-y_{2})*(y_{1}-y_{2}) (x1​−x2​)∗(x1​−x2​)+(y1​−y2​)∗(y1​−y2​)

题目就可以转换为:求所有墨点的完全图 的最小生成树 中的最长的边hu 大喘气

AC代码:

#include<iostream>#include<algorithm>using namespace std;const int N=5005;const long long LLF=9e18;int n;int st[N];long long mp[N][N];long long dist[N];struct Node{long long x,y;}e[N];int main(){//freopen("D:\\in.txt","r",stdin);int T;cin>>T;while(T--){scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%lld%lld",&e[i].x,&e[i].y);dist[i]=LLF;st[i]=0;}long long hp;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(i!=j){hp=(e[i].x-e[j].x)*(e[i].x-e[j].x)+(e[i].y-e[j].y)*(e[i].y-e[j].y);mp[i][j]=hp;}}}dist[1]=0;long long ans=-1;for(int i=0;i<n;i++){hp=-1;for(int j=1;j<=n;j++)if(!st[j]&&(hp==-1||dist[hp]>dist[j]))hp=j;st[hp]=1;ans=max(ans,dist[hp]);for(int j=1;j<=n;j++)dist[j]=min(dist[j],mp[hp][j]);}cout<<ans<<endl;}return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。