最小生成树(kruskal)

来源:互联网 发布:网站备案 知乎 编辑:程序博客网 时间:2024/05/17 01:47

题目:http://poj.org/problem?id=2349

题目大意是有p个村庄,k个雷达,村庄之间的通讯通过雷达和铺电线,雷达无惧距离,每个村庄通过铺电线通讯,电线之间距离不能多余d米,就最短的d.

方法:就是先建立一个完全图,枚举每个村庄之间的距离,从中建立最小生成树,d是最小生成树的第k个最长长度

通过kruskal+并查集。

然而我runtime over到怀疑人生

先附上我的代码

#include <iostream>#include <vector>#include <algorithm>#include <cstring>#include <cmath>#include <cstdio>using namespace std;#define maxn 1000typedef struct node{    double x, y, len;//}node;node s[500005];int sn, p;//sn是雷达, p是村庄int par[maxn], rank[maxn];double a[maxn], b[maxn];int find(int x){    if(par[x]==x)        return x;    else    return par[x] = find(par[x]);}bool cmp(node a, node b){    if(a.len < b.len)        return 1;    return 0;}bool cmp1(double a, double b){    if(a > b)        return 1;    return 0;}int main(){    int t, i, j, k, t1, t2;    double length[maxn];    scanf("%d", &t);    while(t--)    {       k=1;       memset(length, 0, sizeof(length));       memset(s, 0, sizeof(s));       scanf("%d%d", &sn, &p);       for(i=1;i<=p;i++)           scanf("%lf%lf",&a[i], &b[i]);       for(i=1;i<p;i++)          for(j=i+1;j<=p;j++)       {           par[k]=k;           rank[k]=0;           s[k].x=i;           s[k].y=j;           s[k++].len = sqrt((a[i]-a[j])*(a[i]-a[j]) + (b[i]-b[j])*(b[i]-b[j]) );       }       int l=1;       sort(s+1, s+k +1, cmp);       for(i=1;i<k;i++)       {           t1 = find(s[i].x);           t2 = find(s[i].y);           if(t1 != t2)           {               length[l++] = s[i].len;               if(rank[t1] < rank[t2])                 par[t1] = t2;               else{                par[t2]=t1;                if(rank[t1]==rank[t2])                    rank[t1]++;               }           }       }       sort(length+1, length + l +1, cmp1);       printf("%.2lf\n",length[sn]);    }    return 0;}

原创粉丝点击