Arctic Network UVA - 10369 (最小生成树,适合prim)

给出n个点将他们连成最小生成树,给出k个卫星,有了这些卫星就可以无代价地连接一些边。求出在此条件下的最长的边

也就是求出最小生成树的第k小条边

考虑到这个图的边比较多,选择使用prim算法,需要注意的是,先生成的边不一定小,后生成的边也不一定大

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<climits>
#define int long long
#define endl '\n'

using namespace std;
const int inf=LLONG_MAX;
const int size=505;
int loop[size][size];
int vis[size];
int dis[size];
int locx[size];
int locy[size];
int date[size];
int n,k;
int cnt=0;
void prim(int beg)
{
	int ind=beg;
	memset(vis,0,sizeof(vis));
	vis[ind]=1;
	cnt=0;
	for(int i=0;i<n;i++)
	{
		dis[i]=loop[i][ind];
	}
	for(int i=1;i<n;i++)
	{
		int rule=inf;
		for(int j=0;j<n;j++)
		{
			if(!vis[j]&&dis[j]<rule)
			{
				rule=dis[j];
				ind=j;
			}
		}
		date[cnt++]=rule;
		vis[ind]=1;
		for(int j=0;j<n;j++)
		{
			if(!vis[j]&&loop[ind][j]<dis[j])
			{
				dis[j]=loop[ind][j];
			}
		}
	}
}
void pre_solve()
{
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			loop[i][j]=(locx[i]-locx[j])*(locx[i]-locx[j])+(locy[i]-locy[j])*(locy[i]-locy[j]);
		}
	}
}
int32_t main()
{
	int t;
	cin>>t;
	while(t--)
	{
		scanf("%lld%lld",&k,&n);
		for(int i=0;i<n;i++)
		{
			scanf("%lld%lld",&locx[i],&locy[i]);
		}
		pre_solve();
		prim(0);
		sort(date,date+cnt);
		double ans=(double)date[n-k-1];
		printf("%.2f\n",sqrt(ans));
	}
	
	
	return 0;
}

 

posted @ 2018-08-06 20:12  Fly_White  阅读(108)  评论(0编辑  收藏  举报