您的位置:首页 > 其它

HDOJ1875(畅通工程再续)

2012-04-20 22:21 239 查看
题目链接

这题与HDOJ1879有点不太一样,不能把不符合条件的边看成是已经修好的,使用克鲁斯卡尔时,碰到不符合的边直接跳过即可。

View Code

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define D(x1,y1,x2,y2)  (sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)))
#define N 101
#define M 5000
int x
,y
;
struct node
{
int a,b;
double d;
}edge[M];
int n,m,p
;
void make_set()
{
int i;
for(i=0;i<n;i++)   p[i]=i;
}
int find_set(int i)
{
return i==p[i]?p[i]:(p[i]=find_set(p[i]));
}
void union_set(int i,int j)
{
i=find_set(i),j=find_set(j);
p[j]=i;
}
int cmp(const void *a,const void *b)
{
double x,y;
x=((struct node*)a)->d;
y=((struct node*)b)->d;
if(x>y) return 1;
return -1;
}
int main()
{
int t,i,j,cnt;
double ans;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
make_set();
for(i=0;i<n;i++)    scanf("%d%d",&x[i],&y[i]);
m=0;
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
edge[m].a=i,edge[m].b=j;
edge[m++].d=D(x[i],y[i],x[j],y[j]);
}
}
qsort(edge,m,sizeof(edge[0]),cmp);
ans=cnt=0;
for(i=0;cnt<n-1&&i<m;i++)
{
if(find_set(edge[i].a)==find_set(edge[i].b))  continue;
if(edge[i].d<10.0||edge[i].d>1000.0)    continue;
ans+=edge[i].d;
union_set(edge[i].a,edge[i].b);
cnt++;
}
if(cnt==n-1)    printf("%.1lf\n",ans*100);
else    printf("oh!\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: