POJ2349->最小生成树

来源:互联网 发布:windows原版镜像 编辑:程序博客网 时间:2024/06/06 14:49

POJ2349->最小生成树


题意:

要在n个节点之间建立通信网络,其中m个节点可以用卫星直接连接,剩下的节点都要用线路连接,求剩下这些线路中最大的长度需要多长

题解:

明显还是最小生成树的题

如果用Prime算法,该算法现在V1集合中放入任意一个节点,然后每次选取和V1集合中的节点相连的最短的边的另一个节点加入到V1集合。
此时,可以把建成整棵最小生成树的所有边记录在一个数组里,然后排序,dist[n-m]就是答案

如果是kruskal算法,该算法每次选取最短的边,只需选完n-m条边就能得到答案


Prime算法代码:

#include <stdio.h>#include <iostream>#include <string.h>#include <cmath>#include <algorithm>using namespace std ;const double INF = 1000000000 ;#define MAX 550int n ,sum;bool visit[MAX] ;double cost[MAX][MAX] ;double lowc[MAX] ;double dist[MAX] ;struct Node{    double x, y ;}MAP[MAX];double Dis(Node a , Node b){    return sqrt((a.x - b.x)*(a.x - b.x) + (a.y-b.y)*(a.y-b.y)) ;}void init(){    double temp ;    for(int i = 1 ; i <= n ; i ++) cost[i][i] = INF ;    for(int i = 1 ; i <= n ; i ++)    {        for(int j = i+1 ; j <= n ; j ++)        {            temp = Dis(MAP[i] , MAP[j]) ;            cost[i][j] = cost[j][i] =  temp;        }    }}void Prime(){    int cnt = 0 ;    memset(visit , false , sizeof(visit)) ;    visit[1] = true ;    for(int i = 1 ; i <= n ; i ++)    {        lowc[i] = cost[1][i] ;    }    lowc[1] = 0 ;    for(int i = 1 ; i < n ; i ++)    {        double minc = INF ;        int p = -1  ;        for(int j = 1 ; j <= n ; j ++)        {            if(!visit[j] && minc > lowc[j])            {                minc = lowc[j] ;                p = j ;            }        }        //if(minc == INF) break ;        visit[p] = true ;        dist[cnt ++] = minc ;        for(int j = 1 ; j <= n ; j ++)        {            if(lowc[j] > cost[p][j])            {                lowc[j] = cost[p][j] ;            }        }    }    sort(dist , dist + cnt) ;    printf("%.2f\n",dist[cnt - sum]) ;}int main(){    int T ;    scanf("%d" , &T) ;    while(T --)    {        scanf("%d%d" ,&sum , &n) ;        for(int i = 1 ; i <= n ; i ++)        {            scanf("%lf%lf" , &MAP[i].x , &MAP[i].y) ;        }        init() ;        Prime() ;    }    return 0;}
0 0