zoukankan      html  css  js  c++  java
  • poj 2349 Arctic Network MST/二分答案

    poj 2349 Arctic Network

    题目传送

    Sol:

    方法一:

    贪心的想,发现n个点只需要n-1条边即可,求MST即可,再把MST中最大的m-1条边去掉,第m大就是答案。

    code:

    #include<string>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define IL inline
    #define RG register
    #define DB double
    #define LL long long
    using namespace std;
    
    IL int gi() {
    	RG int x=0,p=1; RG char ch=getchar();
    	while(ch<'0'||ch>'9') {if(ch=='-') p=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
    	return x*p;
    }
    
    const int N=507;
    
    DB d[N];
    int n,m,tot,fa[N];
    
    struct DOT{int x,y;}a[N];
    struct EDGE{int x,y;DB d;}e[N*N<<1];
    
    IL bool operator <(EDGE A,EDGE B) {return A.d<B.d;}
    
    IL DB dis(int s,int b) {
    	return sqrt(1.0*(a[s].x-a[b].x)*(a[s].x-a[b].x)+(a[s].y-a[b].y)*(a[s].y-a[b].y));
    }
    
    int getfa(int x) {return fa[x]==x?x:fa[x]=getfa(fa[x]);}
    
    IL void Kruskal() {
    	RG int i,fx,fy,cnt=0;
    	for(i=1;i<=n;++i) fa[i]=i;
    	for(i=1;i<=tot;++i) {
    		fx=getfa(e[i].x),fy=getfa(e[i].y);
    		if(fx==fy) continue;
    		fa[fx]=fy,d[++cnt]=e[i].d;
    		if(cnt==n-1) break;
    	}
    	printf("%.2lf
    ",d[n-m]);//poj 上如用G++交代码,则需把%lf改为%f
    }
    
    int main()
    {
    	RG int i,j,T=gi();
    	while(T--) {
    		m=gi(),n=gi(),tot=0;
    		for(i=1;i<=n;++i) a[i].x=gi(),a[i].y=gi();
    		for(i=1;i<=n;++i)
    			for(j=i+1;j<=n;++j)
    				e[++tot]=(EDGE){i,j,dis(i,j)};
    		sort(e+1,e+tot+1);
    		Kruskal();
    	}
    	return 0;
    }
    //poj 145ms
    

    方法二:

    考虑二分答案,满足条件的点连好边,然后dfs一下有几个连通块,有多少连通块就需要多少卫星,和m比较即可。

    相比方法一,code又慢又长。。。

    code:

    #include<string>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #define IL inline
    #define RG register
    #define DB double
    #define LL long long
    using namespace std;
    
    IL int gi() {
    	RG int x=0,p=1; RG char ch=getchar();
    	while(ch<'0'||ch>'9') {if(ch=='-') p=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
    	return x*p;
    }
    
    const int N=505;
    const DB eps=1e-4;
    
    DB l,r,mid;
    int n,m,cnt,tot,vis[N],head[N];
    
    struct DOT{int x,y;}a[N];
    struct EDGE{int next,to;}e[N*N<<1];
    
    IL void New_case() {
    	tot=cnt=0;
    	memset(&e,0,sizeof(e));
    	memset(vis,0,sizeof(vis));
    	memset(head,0,sizeof(head));
    }
    
    IL void make(int x,int y) {
    	e[++tot]=(EDGE){head[x],y},head[x]=tot;
    	e[++tot]=(EDGE){head[y],x},head[y]=tot;
    }
    
    IL DB dis(int s,int b) {
    	return 1.0*sqrt((a[s].x-a[b].x)*(a[s].x-a[b].x)+(a[s].y-a[b].y)*(a[s].y-a[b].y));
    }
    
    IL void dfs(int x) {
    	RG int i,y;
    	vis[x]=1;
    	for(i=head[x];i;i=e[i].next)
    		if(!vis[y=e[i].to]) dfs(y);
    }
    
    IL int check(DB val) {
    	RG int i,j;
    	New_case();
    	for(i=1;i<=n;++i)
    		for(j=i+1;j<=n;++j)
    			if(dis(i,j)<=val) make(i,j);
    	for(i=1;i<=n;++i)
    		if(!vis[i]) dfs(i),++cnt;
    	return cnt<=m;
    }
    
    int main()
    {
    	RG int i,T=gi();
    	while(T--) {
    		m=gi(),n=gi();
    		for(i=1;i<=n;++i) a[i].x=gi(),a[i].y=gi();
    		l=0,r=1e9;
    		while(r-l>=eps) {
    			mid=(l+r)/2;
    			if(check(mid)) r=mid;
    			else l=mid;
    		}
    		printf("%.2lf
    ",r);
    	}
    	return 0;
    }
    // poj 1400多ms
    
  • 相关阅读:
    mysql视图产生派生表无法优化案例
    根据.frm .ibd文件恢复表
    binlog内容时间乱序问题排查
    mysql官方的测试数据库employees超30万的数据,安装方法介绍
    数据库大量Waiting for table flush 状态SQL问题排查
    mysql搭建从库并配置ssl
    MySQL lOAD DATA详解
    redis eval
    aws-rds for mysql 5.7.34时间点恢复数据
    MySQL 如何处理监听连接的
  • 原文地址:https://www.cnblogs.com/Bhllx/p/11247350.html
Copyright © 2011-2022 走看看