poj 2349 Arctic Network MST/二分答案

Posted bhllx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 DOTint x,y;a[N];
struct EDGEint 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\n",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 DOTint x,y;a[N];
struct EDGEint 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\n",r);
    
    return 0;

// poj 1400多ms

以上是关于poj 2349 Arctic Network MST/二分答案的主要内容,如果未能解决你的问题,请参考以下文章

Arctic Network——最小生成树

UVA10369 Arctic Network

poj2349

[kuangbin带你飞]专题六 最小生成树 G - Arctic Network

poj2349最小生成树prim

POJ2349(求生成树中符合题意的边)