首页 > 其他 > 详细

洛谷 P1991 无线通讯网

时间:2019-08-29 21:55:59      阅读:88      评论:0      收藏:0      [点我收藏+]

前言

许久都没有做过图论题了,今天晚上刷了几道MST(最小生成树) 的题目,其中有一道题目还是很不错,在这里给大家推荐一下

题目描述

链接在这里 : https://www.luogu.org/problem/P1991

思路

看了题目之后,我们可以很清楚的知道题目需要我们先求连接所有哨所的最小花费,这时候这种连接点并求花费的算法自然就出来了,这里我们使用 Kruskal算法 

步骤

一、我们先预处理任意两点的距离,存入结构体定义的边中

二、根据 Kruskal算法 的流程进行操作,当所有点被连上,退出

三、这时候答案就在way数组里第top-(s-1)中

AC CODE

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 using namespace std;
 7 const int N=502;
 8 const int M=150000;
 9 struct data{
10     int x;
11     int y;
12 }pt[N];
13 struct edge{
14     int st;
15     int ed;
16     double val;
17 }eg[M];
18 int tot=0;
19 int s,p;
20 int fa[N];
21 double way[M];
22 int top=0;
23 double ans;
24 int find(int x)
25 {
26     if (fa[x]==x) return x;
27     fa[x]=find(fa[x]);
28     return fa[x];
29 }
30 inline void un(int x,int y)
31 {
32     int fx=find(x);
33     int fy=find(y);
34     if (fx!=fy)
35     fa[fx]=fy;
36     return;
37 }
38 double cd(int x1,int y1,int x2,int y2)
39 {
40     return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
41 }
42 bool cmp(edge a,edge b)
43 {
44     return a.val<b.val;
45 }
46 int main()
47 {
48     scanf("%d %d",&s,&p);
49     
50     for (int i=1;i<=p;i++)
51     fa[i]=i;
52     
53     for (int i=1;i<=p;i++)
54     scanf("%d %d",&pt[i].x,&pt[i].y);
55     
56     for (int i=1;i<=p;i++)
57     for (int j=i+1;j<=p;j++)
58     {
59         int x1=pt[i].x,y1=pt[i].y;
60         int x2=pt[j].x,y2=pt[j].y;
61         double dis=cd(x1,y1,x2,y2);
62         eg[++tot].st=i,eg[tot].ed=j,eg[tot].val=dis;
63     }
64     sort(eg+1,eg+tot+1,cmp);
65     
66     int cnt=0;
67 
68     for (int i=1;i<=tot;i++)
69     {
70         int u=eg[i].st;
71         int v=eg[i].ed;
72         double w=eg[i].val;
73         if (find(u)!=find(v))
74         {
75             un(u,v);
76             way[++top]=w;
77             ++cnt;
78         }
79         if (cnt==p-1) break;
80     }
81     ans=way[top-(s-1)];
82     printf("%.2lf",ans);
83     return 0;
84 }

 

关键

根据 Kruskal算法 我们的边都是从小到大排序,所以后加的边较大

一共 S 台卫星电话,所以可以连接最后的 S-1 点 

所以最小的D就在 way[top-(s-1)]

 

洛谷 P1991 无线通讯网

原文:https://www.cnblogs.com/Snowindfly/p/11432040.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!