题意:给出n个点坐标 一个人经过m个不同坐标 最少一口气需要跑多远
解法 :对每个距离从小到大排序 并查集直到有一个集合并入m个坐标 就输出当前距离
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define clr(x)memset(x,0,sizeof(x))
int father[600];
int b[600];
int n,m,i,j,flag;
double res;
struct node
{
int x,y;
double dist;
}e[600*600];
int cmp(node a,node b)
{
return a.dist<b.dist;
}
int find(int x)
{
if(father[x]==x)return x;
return father[x]=find(father[x]);
}
bool join(int x,int y)
{
x=find(x);
y=find(y);
if(x==y)return false;
if(x>y){father[x]=y;b[y]+=b[x];if(b[y]>=m&&flag==0){flag=1;res=e[i].dist;printf("%.4lf\n",res);}}
if(x<y){father[y]=x;b[x]+=b[y];if(b[x]>=m&&flag==0){flag=1;res=e[i].dist;printf("%.4lf\n",res);}}
return true;
}
int x[600];
int y[600];
int main()
{
int n,T;
scanf("%d",&T);
while(T--)
{
flag=0;
int tot=0;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
{
scanf("%d%d",&x[i],&y[i]);
}
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
e[tot].x=i;
e[tot].y=j;
e[tot++].dist=sqrt((double)(x[i]-x[j])*(x[i]-x[j])+(double)(y[i]-y[j])*(y[i]-y[j]));
}
}
for(i=0;i<=n;i++)
{
father[i]=i;
b[i]=1;
}
sort(e,e+tot,cmp);
for(i=0;i<tot;i++)
{
join(e[i].x,e[i].y);
}
}
return 0;
}
hrbust 1679 跑步
最新推荐文章于 2019-03-21 23:20:28 发布