最小生成树

View Code
 1  #include<iostream>
 2  #include<cmath>
 3  #include<algorithm>
 4  using namespace std;
 5  #define Max 501
 6  double map[Max][Max],d[Max];
 7  int n,i,j;
 8  struct{
 9      int x,y;
10  }point[Max];
11  //记录从顶点集U到V-U的代价最小的边的辅助数组定义
12  struct{
13      int adjvex;
14      double lowcost;
15  }closedge[Max];
16  bool cmp(double a,double b)//从大到小偏序
17  {
18      return a>b;
19  }
20  //用普里姆算法从第k个顶点出发构造网G的最小生产树T
21  void prim(int k)
22  {
23      for(j=1;j<=n;j++)//辅助数组初始化
24          if(j!=k)
25          {
26              closedge[j].adjvex=k;
27              closedge[j].lowcost=map[k][j];
28          }
29      closedge[k].lowcost=0; //初始,U={u}
30      int l=0;
31      for(i=1;i<n;i++)//选择其余n-1个顶点
32      {
33          double min=1000000;
34          for(j=1;j<=n;j++)//求出T的下一个结点:第k顶点
35              if(closedge[j].lowcost!=0&&min>closedge[j].lowcost)
36              {
37                  k=j;
38                  min=closedge[j].lowcost;
39              }
40          closedge[k].lowcost=0; //第k顶点并入U集
41          d[l++]=map[k][closedge[k].adjvex]; //保存该边
42          for(j=1;j<=n;j++) //新顶点并入U后重新选择最小边
43              if(map[k][j]<closedge[j].lowcost)
44              {
45                  closedge[j].adjvex=k;
46                  closedge[j].lowcost=map[k][j];
47              }
48      }
49  }
50  int main()
51  {
52      int t,m;
53      cin>>t;
54      while(t--)
55      {
56          cin>>m>>n;
57          for(i=1;i<=n;i++)
58              cin>>point[i].x>>point[i].y;
59          for(i=1;i<=n;i++) //求出毎两个顶点之间的距离
60              for(j=1;j<i;j++)
61                  map[i][j]=map[j][i]=sqrt((point[i].x-point[j].x)*(point[i].x
62                  -point[j].x)+(point[i].y-point[j].y)*(point[i].y-point[j].y));
63          for(i=1;i<=n;i++)
64              map[i][i]=1000000;
65          prim(1);
66          sort(d,d+n-1,cmp); //把构成最小生成树的n-1条边从大到小排序
67          cout.setf(ios::fixed);//保留两位小数
68          cout.precision(2);
69          cout<<d[m-1]<<endl;//数组d从下标0开始存储,即第m条边
70      }
71      return 0;
72  }

 

转载于:https://www.cnblogs.com/myacm/archive/2012/08/08/2628378.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值