洛谷1991无线通讯网 生成树的应用

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

解法:选择S个点,使得另外的P-S个点到这S个点构成的联通分量U的最大距离最小。我们可以考虑最小生成树的最大边,可以证明最小生成树的最大边一定在U中,否则最大值就是该边长度,之后我们可以迭代地将最小生成树的次大边放入U中,直到一共放入了S-1条边,也就是最大距离的最小值就是最小生成树的第(P-1)-(S-1)=P-S条最小边。

代码如下:

 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 point{
30     int x,y;
31 }p[maxn];
32 struct node{
33     int u,v;
34     double dis;
35 }e[maxn];
36 double dis(int i,int j)
37 {
38     int x=p[i].x,y=p[i].y,xx=p[j].x,yy=p[j].y;
39     return  sqrt((double)(x-xx)*(x-xx)+(double)(y-yy)*(y-yy));
40 }
41 int cnt=0,num=0;
42 double ans=0.0;
43 int f[maxn];
44 bool cmp(node& a,node& b)
45 {
46     return a.dis<b.dis;
47 }
48 int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
49 void Union(int x,int y)
50 {
51     int fx=find(x);
52     int fy=find(y);
53     if(fx==fy)return;
54     else f[fx]=fy,num++;
55 }
56 int main()
57 {
58     //freopen("input.txt","r",stdin);
59     //freopen("output.txt","w",stdout);
60     std::ios::sync_with_stdio(false);
61     m=read(),n=read();
62     f(i,1,n)f[i]=i;
63     f(i,1,n)
64     {
65         p[i].x=read(),p[i].y=read();
66      }
67      f(i,1,n)
68          f(j,1,n)
69          {
70              if(i>=j)continue;
71              e[++cnt].u=i,e[cnt].v=j,e[cnt].dis=dis(i,j);
72           }
73           sort(e+1,e+cnt+1,cmp); 
74           f(i,1,cnt)
75           {
76               Union(e[i].u,e[i].v); 
77               if(num==n-m)
78               {
79                   ans=e[i].dis;
80                   break;
81               }
82           }
83           pf("%.2lf",ans);
84 } 

 

posted @ 2020-03-26 11:50  WA自动机~  阅读(136)  评论(0编辑  收藏  举报