poj 2349 Arctic Network

————————————————————————————————————————————————

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

————————————————————————————————————————————————

这是别人的代码, 但我觉得有学习之处,这道题自己的思路使用并查集,kruskal算法,

但代码很繁琐,将近百行,而这段代码用的是那种思想,而不是生搬硬套算法结构,这一点我备受启发,

对自己学习算法指明了一个方向,对自己以前的学习方式也是一种反思 !!!

————————————————————————————————————————————————

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

————————————————————————————————————————————————

#include<iostream>
#include<cstdio>
#include<cstring>
#include<math.h>
#include<vector>
#include<algorithm>
#include<set>
#include<queue>
using namespace std;

int n, k;
int pre[510];

//存边
struct e{
    int x, y;
    double z;
}a[251000];

int find(int x){
    while(x!=pre[x]){
        x=pre[x];
    }
    return x;
}

int cmp(e a,e b){
    return a.z<b.z;
}

int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int s, p;
        scanf("%d%d",&s,&p);
        
        //初始化父节点
        for(int i = 1; i <= p; i++){
            pre[i] = i;
        }
        
        double x[510], y[510];
        int k = 0;
        
        //对边集进行赋值
        for(int i = 1; i <= p; i++){
            scanf("%lf%lf", &x[i], &y[i]);
            for(int j = 1; j < i; j++){
                a[k].x = i;
                a[k].y = j;
                a[k++].z = sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
            }
        }
        //排序
        sort(a, a+k, cmp);
        
        //问题转化,总的哨所减去卫星频道数就是需要建立无线电通讯的数量
        
        int num = p-s;
        
        double res = 0;
        for(int i = 0; i < k; i++){ //合并,寻找最小生成树
            int dx = find(a[i].x);    
            int dy = find(a[i].y);
            if(dx!=dy){             //不成环
                pre[dx]=dy;  
                num--;               
                res=a[i].z;         //记录最后添加的变长,即答案
            }
            if(num==0) break;
        }
        printf("%.2f\n", res);
    }
}

你可能感兴趣的:(C++,算法,ACM,poj,kruskal)