zoukankan      html  css  js  c++  java
  • 无线通讯网(双倍经验)

    无线通讯网

    洛谷P1991 无线通讯网

    前言

    这是一道明显的图论题,主要有两种做法:

    最小生成树(Kruskal/Prim)、二分&并查集

    本篇题解使用第一种做法解决,如果有不懂最小生成树的可以自己先学习一下(能做到这题应该会

    最小生成树的学习记录写完后,会挂在这里,欢迎各位来踩qwq


    引入

    PS:题意直接点击链接即可,还是很简明易懂的,就不多赘述

    读完题没有思路,那就对样例下手吧,见图(几何画板真是个好东西啊)

    再将这些距离从小到大排个序(因为要求最短距离嘛):

    200 < 212.13 < 300 < 474.34 < 500 < 667.08
    

    很明显,要使问题中的无线电收发器的传输距离最小,那么667.08这个距离肯定要避免:所以两个超级电话就安在A、D点,剩下B、C两点,而答案很明显就是212.13

    思路推导

    • 将样例转换为一般性问题讨论:

    因为题目已经说明任意两点只要直接或间接连接即可,所以我们不需要p条边构造完全图,而只需要p-1条边构造为一棵树

    上面s个超级电话之间肯定有(s-1)条边,所以我们还只剩下(p-1-(s-1))=(p-s)条边需要构造

    • 转换样例推导出思路:

    我们就可以直接构造最小生成树了呀!构造的最小生成树包含(p-s)条边,剩下的(s-1)条边直接留给超级电话即可


    代码Code

    明确了思路,这题的代码也就是小问题了,建议大家可以先自己编写啊

    现在给出AC代码(使用Kruskal求解最小生成树):

    #include <bits/stdc++.h>
    using namespace std;
    double ans;
    int s,p,sx,sy,tot,now,x[2010],y[2010],fa[2010];
    
    struct node {
    	int u,v;
    	double w;
    } e[2010];
    
    inline bool cmp(node xx,node yy) {
    	return xx.w<yy.w;
    }
    
    inline int find(int x) {
    	if(fa[x]==x) return x;
    	return fa[x]=find(fa[x]);
    }
    
    int main() {
    	scanf("%d%d",&s,&p);
    	for(register int i=1;i<=p;i++) {
    		fa[i]=i;
    		scanf("%d%d",&x[i],&y[i]);
    		for(register int j=1;j<i;j++) {  //计算每两个点之间的距离(也可以单独开两层循环处理) 
    			e[++tot].u=i;
    			e[tot].v=j;
    			e[tot].w=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
    		}
    	}
    	sort(e+1,e+1+tot,cmp);   //Kruskal求解最小生成树 
    	for(register int i=1;i<=tot;i++) {
    		int a=find(e[i].u);
    		int b=find(e[i].v);
    		if(a!=b) {
    			fa[a]=b;
    			ans=e[i].w;  //因为已经排过序,所以直接更新即可 
    			now++;
    		}
    		if(now==p-s) break;  //如分析,最小生成树只包含p-s条边,剩余的s-1条边使用超级电话解决 
    	}
    	printf("%.2lf",ans);  //题目要求,保留两位小数输出 
    	return 0;
    } 
    

    双倍经验

    洛谷P4047 [JSOI2010]部落划分

    这道题只有判断最小生成树构造完成的判断与无线通讯网不同

    简单描述一下思路:给定k个部落,相当于可以少连 (k-1) 条边,和卫星电话是差不多的

    但是在查找答案时,应该多判断一条边,因为要求是不同部落间的最短距离最大

    所以判断改为:if(now==n-k+1) break;


  • 相关阅读:
    struts2基础
    javaEE环境搭建-eclipse
    geth
    redis常用命令
    angular-ui-select 下拉框支持过滤单选多选解决方案(系列一)
    angularjs中向html页面添加内容节点元素代码段的两种方法
    modal
    弹性布局
    自定义鼠标样式
    angularjs指令弹框点击空白处隐藏及常规方法
  • 原文地址:https://www.cnblogs.com/Eleven-Qian-Shan/p/13192695.html
Copyright © 2011-2022 走看看