zoukankan      html  css  js  c++  java
  • 洛谷1265prim算法求最小生成树

    题目链接:https://www.luogu.com.cn/problem/P1265

    最小生成树的prim算法跟dijkstra算法非常像,就是将点分成两个集合,一个是已经在生成树中的点的集合,一个是还未加入生成树的点的集合。最初选择一个点进入集合{V1},然后从{V}-{V1}点集中选择到{V1}距离最短的点进入点集{V1},这样迭代地操作下去,直到所有的点都已经访问过。其实这就是一个合并连通分量的过程,每次都选择最小的合并代价进行合并,最终由局部最优解得出全局最优解,至于最小生成树的算法的正确性的严格的证明,请见我的另一篇博客,本人菜鸡一枚,有错误还请指正。

    代码如下:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef unsigned int ui;
     4 typedef long long ll;
     5 typedef unsigned long long ull;
     6 #define pf printf
     7 #define mem(a,b) memset(a,b,sizeof(a))
     8 #define prime1 1e9+7
     9 #define prime2 1e9+9
    10 #define pi 3.14159265
    11 #define lson l,mid,rt<<1
    12 #define rson mid+1,r,rt<<1|1
    13 #define scand(x) scanf("%llf",&x) 
    14 #define f(i,a,b) for(int i=a;i<=b;i++)
    15 #define scan(a) scanf("%d",&a)
    16 #define mp(a,b) make_pair((a),(b))
    17 #define P pair<int,int>
    18 #define dbg(args) cout<<#args<<":"<<args<<endl;
    19 #define inf 0x3f3f3f3f
    20 const int maxn=1e6+10;
    21 int n,m,t;
    22 inline int read(){
    23     int ans=0,w=1;
    24     char ch=getchar();
    25     while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
    26     while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
    27     return ans*w;
    28 }
    29 struct node{
    30     int x,y;
    31 }e[maxn];
    32 double ans;
    33 double d[maxn];
    34 int vis[maxn];
    35 double dis(int i,int j)
    36 {
    37     int x=e[i].x,y=e[i].y,xx=e[j].x,yy=e[j].y;
    38     return sqrt((double)(x-xx)*(x-xx)+(double)(y-yy)*(y-yy));
    39 }
    40 void prim()
    41 {
    42     mem(vis,0);
    43     f(i,1,n)d[i]=inf; 
    44     d[1]=0;
    45     f(i,1,n)//迭代次数,为n次 
    46     {
    47         int pos;
    48         double tmp;
    49         tmp=inf,pos=-1;
    50         f(j,1,n)
    51         {
    52                 if(!vis[j]&&d[j]<tmp)
    53                 {
    54                     tmp=d[j],pos=j;//找出到点集最小的边的长度和编号 
    55                 }
    56         }
    57         if(tmp==inf) return;
    58         vis[pos]=1;
    59         ans+=tmp;
    60         f(j,1,n)//刚标记过的点对剩余的点进行松弛操作 
    61         {
    62             if(!vis[j]) 
    63             d[j]=min(d[j],dis(pos,j));
    64         }
    65     } 
    66 }
    67 int main()
    68 {
    69     //freopen("input.txt","r",stdin);
    70     //freopen("output.txt","w",stdout);
    71     std::ios::sync_with_stdio(false);
    72      n=read();
    73      f(i,1,n)
    74      {
    75          e[i].x=read(),e[i].y=read();
    76     } 
    77      prim();
    78      pf("%.2lf",ans);
    79 } 

     

  • 相关阅读:
    android 样式开发
    Android studio 开发环境搭建
    nodejs+express 4.x笔记
    C#: switch语句的重构『网摘』
    从实例谈OOP、工厂模式和重构
    ASP.NET FileUpload 上传文件类型验证
    asp.net 网页中播放 flash 和flv
    数据库设计中主键问题
    修改Sqlserver实例默认排序规则
    查看sqlserver被锁的表以及如何解锁
  • 原文地址:https://www.cnblogs.com/randy-lo/p/12571635.html
Copyright © 2011-2022 走看看