1393: 国防部长PIPI

题目描述

PIPI国有n个哨所,每个哨所都配置了一台型号相同的无线电通讯设备。设备有一个通讯半径D,如果两个哨站距离超过D,就无法直接通讯。
无线电通讯设备功率越高,通讯半径就越大,但是造价也就越高。为了省钱,PIPI需要确定一个最小的通讯半径D,所有的哨站使用这一型号设备后,任意两个哨站都能进行通讯(直接或间接)。

输入

多组测试用例
第一行为整数n,表示哨所的数目。2<=n<=100。
接下来n行,每行给出一个坐标(x,y),表示第i个哨所的坐标。-50000<=x,y<=50000.

输出

每组数据输出一个实数,表示D的最小值。保留两位小数。

样例输入

4
0 100
0 300
0 600
150 750

样例输出

300.00
方法一:克鲁斯卡尔

#include<bits/stdc++.h>
using namespace std;
int n;
typedef pair<int,int> pr;
pr point[105];
struct node{
	int x,y;
	double d;
	bool operator<(const node &tmp) const{
		return d<tmp.d;
	}
}E[10003];
double cal(pr a,pr b){
	return 1ll*(a.first-b.first)*(a.first-b.first)+1ll*(a.second-b.second)*(a.second-b.second);
}
int father[105];
int _find(int x) {return x==father[x]?x:father[x]=_find(father[x]);}
int main(){
	while(scanf("%d",&n)!=EOF){
		for(int i=1;i<=n;i++){
			scanf("%d%d",&point[i].first,&point[i].second);
			father[i]=i;
		}
		int tot=0;
		for(int i=1;i<=n;i++){
			for(int j=i+1;j<=n;j++){
				E[tot++]={i,j,cal(point[i],point[j])};
			}
		}
		double ans=0;
		sort(E,E+tot);
		for(int i=0;i<tot;i++){
			int fa=_find(E[i].x),fb=_find(E[i].y);
			if(fa!=fb){
				father[fa]=fb;
				ans=E[i].d;
			}
		}
		printf("%.2f\n",sqrt(ans));	
	}
} 

方法二:普里姆

#include <bits/stdc++.h>
using namespace std;
int n;
const int INF=1e9;
double mp[105][105];
double x[105],y[105];
double dis[105];
bool vis[105];
double sum;
void prim() ///prim求最小生成树
{
    sum=0;
    for(int i=1; i<n; i++){
        dis[i]=mp[0][i];
    }
    vis[0]=1;
    for(int i=1; i<n; i++)
    {
        double minn=INF;
        int minid;
        for(int j=1; j<n; j++)
        {
            if(!vis[j]&&dis[j]<minn)
            {
                minn=dis[j];
                minid=j;
            }
        }
        sum=max(sum,minn);
        vis[minid]=1;
        for(int j=1; j<n; j++)
        {
            if(!vis[j]&&dis[j]>mp[minid][j])
            {
                dis[j]=mp[minid][j];
            }
        }
    }
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        memset(mp,0,sizeof(mp));
        memset(vis,0,sizeof(vis));
        for(int i=0; i<n; i++)
        {
            scanf("%lf%lf",&x[i],&y[i]);
        }
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                mp[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); ///建图
            }
        }
        prim();
        printf("%.2lf\n",sum);
    }
    return 0;
}
发布了78 篇原创文章 · 获赞 7 · 访问量 4557

猜你喜欢

转载自blog.csdn.net/weixin_44433678/article/details/104894888