..................................................................................................................................................................................................................................................................................................
首先注意数组开的大小,必须大于100*100。
将题目中给的坐标转换成点,再利用并查集,比较简单,
..................................................................................................................................................................................................................................................................................................
代码:
#include<stdio.h>
#include <iostream>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#include<list>
#include<vector>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std;
#define MAX 11000
int father[MAX];
struct edge //结构体定义点与点和距离
{
int x;
int y;
double w;
};
edge e[MAX];
bool cmp(edge o1,edge o2) //排序 升序
{
if(o1.w<o2.w)
{
return true;
}
else
return false;
}
int Find_Set(int x) //查找x元素所在的集合,回溯时压缩路径
{
if(x!=father[x])
{
father[x]=Find_Set(father[x]); //这个回溯时的压缩路径的精华
}
return father[x];
}
int Union(int x,int y)//合并x,y所在的集合
{
x=Find_Set(x);
y=Find_Set(y);
if(x==y)return 0;
else
{
father[x]=y;
}
return 1;
}
int main()
{
int n,m,x,t,y,i,j,count,k;
int a[MAX],b[MAX];
double sum;
double h;
scanf("%d",&t);
while(t--)
{
sum=0.0;
count=0;
k=1;
father[0]=0;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d%d",&a[i],&b[i]);
}
for(i=1;i<=n-1;i++)
for(j=i+1;j<=n;j++)
{
h=(a[j]-a[i])*(a[j]-a[i])+(b[j]-b[i])*(b[j]-b[i]);// 利用两点之间的距离公式
if(h>=100&&h<=1000000)
{
father[k]=k;
e[k].x=i;
e[k].y=j;
e[k].w=sqrt(h);
k++;
}
}
sort(e,e+k,cmp);
for(i=1;i<=k;i++)
{
if(Union(e[i].x,e[i].y))
{
count++;
sum+=e[i].w;
}
}
if(count==n-1)
printf("%.1lf\n",sum*100.0);
else
printf("oh!\n");
}
return 0;
}
#include <iostream>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#include<list>
#include<vector>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std;
#define MAX 11000
int father[MAX];
struct edge //结构体定义点与点和距离
{
int x;
int y;
double w;
};
edge e[MAX];
bool cmp(edge o1,edge o2) //排序 升序
{
if(o1.w<o2.w)
{
return true;
}
else
return false;
}
int Find_Set(int x) //查找x元素所在的集合,回溯时压缩路径
{
if(x!=father[x])
{
father[x]=Find_Set(father[x]); //这个回溯时的压缩路径的精华
}
return father[x];
}
int Union(int x,int y)//合并x,y所在的集合
{
x=Find_Set(x);
y=Find_Set(y);
if(x==y)return 0;
else
{
father[x]=y;
}
return 1;
}
int main()
{
int n,m,x,t,y,i,j,count,k;
int a[MAX],b[MAX];
double sum;
double h;
scanf("%d",&t);
while(t--)
{
sum=0.0;
count=0;
k=1;
father[0]=0;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d%d",&a[i],&b[i]);
}
for(i=1;i<=n-1;i++)
for(j=i+1;j<=n;j++)
{
h=(a[j]-a[i])*(a[j]-a[i])+(b[j]-b[i])*(b[j]-b[i]);// 利用两点之间的距离公式
if(h>=100&&h<=1000000)
{
father[k]=k;
e[k].x=i;
e[k].y=j;
e[k].w=sqrt(h);
k++;
}
}
sort(e,e+k,cmp);
for(i=1;i<=k;i++)
{
if(Union(e[i].x,e[i].y))
{
count++;
sum+=e[i].w;
}
}
if(count==n-1)
printf("%.1lf\n",sum*100.0);
else
printf("oh!\n");
}
return 0;
}