POJ2349

题意

给出(T)组数据,每组数据第一行给出(s)(p),分别代表卫星数和哨所数,接下来给出(p)行代表(p)个哨所的坐标。

带有卫星的两个哨所,相互之间可以进行通信;否则 需要俩哨所之间距离小于等于(d)才可以通过无线电通信。

我们需要满足每个哨所之间都有路径,确定最小的(d)

输出连接网络所需的最小(d),答案保留2个小数点。

PS:我感觉这个英文还是右点难理解,毕竟中文我都看了半天……

思路

这题不难,最小生成树改一下就可以过,但是我写了2h+……

首先我们需要知道一个定理

如果去掉所有权值大于(d)的边后最小生成树被分割成k个连通分支,图也会被分割成k个连通分支。

所以,由此可得,我们只需要给每个连通支分一个卫星即可,最短距离(D)就变成了去掉 大于(D) 后的 最大的边 ,

(X)长的边

AC代码

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<cmath>
#include<list>
#include<stdlib.h>
#include<map>
#include<stack>
#include<stdio.h>
#include<queue>
using namespace std;
typedef long long ll;
#define sc(T) scanf("%d",&T)
#define scc(x,y) scanf("%d %d",&x,&y)
#define pr(T) printf("%d
",T)
#define f(a,b,c) for (int a=b;a<c;a++)
#define ff(a,b,c) for (int a=b;a>c;a--)
#define inf 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define eps 1e-9
#define PI acos(-1)

const int N=520;
int s,p,f[N];
double book[N*N];
struct node
{
    int x,y; //记住!!!改为double结果不对?为啥!?
    double w;
} e[N*N],dis[N*N];

int getf(int x)
{
    if(x==f[x])
        return x;
    return f[x]=getf(f[x]);
}

int merge(int x,int y)
{
    int t1=getf(x);
    int t2=getf(y);
    if(t1!=t2)
    {
        f[t2]=t1;
        return 1;
    }
    return 0;
}

bool cmp1(node x,node y)
{
    return x.w<y.w;
}

double d(node a,node b)
{
    return sqrt(1.0*(a.x-b.x)*(a.x-b.x)+1.0*(a.y-b.y)*(a.y-b.y));
}

int main()
{
    int T;
    sc(T);
    while(T--)
    {
        mem(book,0);
        scc(s,p);//卫星数、哨所数
        for(int i=1; i<=p; i++)
        {
            f[i]=i;
            scc(e[i].x,e[i].y);
        }
        int k=0;
        for(int i=1; i<p; i++)
        {
            for(int j=i+1; j<=p; j++)
                // f(j,0,p)
                dis[k].x=i,dis[k].y=j,dis[k++].w=d(e[i],e[j]);
        }
        sort(dis,dis+k,cmp1);
//        for(int i=0;i<k;i++)
//        {
//            cout<<dis[i].x<<"**"<<dis[i].y<<"***"<<dis[i].w<<endl;
//        }
        int w=0,cnt=0;
        for(int i=0; i<k; i++)
        {
            if(merge(dis[i].x,dis[i].y))
                book[w++]=dis[i].w,cnt++;
            if(cnt==p-1)
            {
                //book[w++]=dis[i].w;
                break;
            }
        }
        sort(book,book+w);
//        for(int i=0;i<w;i++)
//            cout<<book[i]<<"***"<<endl;
        printf("%.2f
",book[p-1-s]);//w-p+1//p-1-s
    }
    return 0;
}
原文地址:https://www.cnblogs.com/OFSHK/p/13712856.html