• 洛谷 P1783 海滩防御(最小生成树)


    传送门


    解题思路

    和上一道题基本相同。
    但是这个题题面是真的复杂,读了好久才读懂。
    关键在于如何建图。
    将在第0列可以看做第0个点,第n列可以看做第m+1个点。
    这两个特殊的点到其他点的距离为点线垂直距离,其他的点之间的距离为点点距。
    还有不同的地方就是两个信号塔之间的距离是两个半径,而0点和m+1点到其他点的距离一个半径,建图时将其中一个除以2或者另一个乘2即可。

    AC代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<iomanip>
    using namespace std;
    const int maxn=1005;
    int n,m,fa[maxn],cnt;
    double ans;
    struct node{
    	int u,v;
    	double w;
    }e[maxn*maxn];
    struct Node{
    	double x,y;
    }a[maxn];
    bool cmp(node a,node b){
    	return a.w<b.w;
    }
    int find(int x){
    	if(fa[x]==x) return x;
    	return fa[x]=find(fa[x]);
    }
    double getdis(int i,int j){
    	return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y))/2;
    }
    int main(){
    	ios::sync_with_stdio(false);
    	cin>>n>>m;
    	for(int i=0;i<=m+1;i++) fa[i]=i;
    	for(int i=1;i<=m;i++){
    		cin>>a[i].x>>a[i].y;
    	}
    	for(int i=1;i<=m;i++) {
    		e[++cnt].u=0;
    		e[cnt].v=i;
    		e[cnt].w=a[i].x;
    		
    		e[++cnt].u=i;
    		e[cnt].v=m+1;
    		e[cnt].w=(n-a[i].x);
    	}
    	for(int i=1;i<m;i++){
    		for(int j=i+1;j<=m;j++){
    			e[++cnt].u=i;
    			e[cnt].v=j;
    			e[cnt].w=getdis(i,j);
    		}
    	}
    	sort(e+1,e+cnt+1,cmp);
    	for(int i=1;i<=cnt;i++){
    		ans=e[i].w;
    		int x=find(e[i].u),y=find(e[i].v);
    		if(x!=y){
    			fa[x]=y;
    		}
    		if(find(0)==find(m+1)) break;
    	}
    	cout<<fixed<<setprecision(2)<<ans;
    	return 0;
    }
    
  • 相关阅读:
    Hive问题
    VirtualBox安装增强功能
    Shell脚本 数据清洗
    团队项目第一阶段冲刺站立会议06
    梦断代码阅读笔记1
    团队项目第一阶段冲刺站立会议05
    团队项目第一阶段冲刺站立会议04
    团队项目第一阶段冲刺站立会议03
    团队项目第一阶段冲刺站立会议02
    团队项目第一阶段冲刺站立会议01
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/15328414.html
Copyright © 2020-2023  润新知