zoukankan      html  css  js  c++  java
  • loj6322 Star Way To Heaven Prim

    Solution

    首先想到二分答案,建图,判断上下边界是否联通,复杂度(O(k^2logn)),不能接受

    由联通,所以想到最小生成树,在最小生成树中,从下边界到上边界路径上最长的边 应该就是限制上下边界联通的边,拿它除以 2 就是答案
    此题边数 (m = k^2),选择prim (O(k^2)) ,因为kruskal 是 (O(mlogm))
    如果怕精度问题可以用 longlong 存下距离的平方

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define rint register int
    using namespace std;
    const int maxn=6e3+5;
    int n,m,k;
    int x[maxn],y[maxn];
    double dis[maxn];
    bool vis[maxn];
    double cal(int i,int j){
    	if(i>j) swap(i,j);
    	if(i==0&&j==k) return (double)m;
    	if(i==0) return (double) y[j];
    	if(j==k) return (double) (double)m-y[i];
    	return (double)sqrt((double)(x[i]-x[j])*(x[i]-x[j])+(double)(y[i]-y[j])*(y[i]-y[j]));
    }
    int main(){
    //	freopen("1.in","r",stdin);
    	scanf("%d%d%d",&n,&m,&k);
    	for(rint i=1;i<=k;++i) scanf("%d%d",&x[i],&y[i]);
    	k++;
    	for(rint i=1;i<=k;++i) dis[i]=1e18;
    	for(rint i=1;i<=k+1;++i){
    		double min_dis=1e18;
    		rint x=-1;
    		for(rint j=0;j<=k;++j){
    			if(!vis[j] && min_dis>dis[j]){
    				x=j; min_dis=dis[j];
    			}
    		}
    		if(x==k){ printf("%.8lf
    ",dis[k]/2);return 0;}
    		vis[x]=1;
    		for(rint j=1;j<=k;++j) if(!vis[j]) dis[j]=min(dis[j],max(dis[x],cal(x,j))); // dis[j] 是MST中j到下边界路径上最大边长(因为MST上不断拓展的新点dis单调不减,所以这样也可以求出MST)
    	}
    	return 0;
    }
    
  • 相关阅读:
    Thinkphp6.0/TP6框架中新增函数的解释及用法
    PHP7.1的几个新特性
    tp6数据库mysql调试
    nginx基本配置
    redis配置
    redis的笔记
    thinkphp学习笔记
    vsCode软件相关快捷键
    erlang随笔3--OTP
    文献综述二十:基于UML技术的客户关系管理系统实现
  • 原文地址:https://www.cnblogs.com/Lour688/p/13810366.html
Copyright © 2011-2022 走看看