力扣 1584. 连接所有点的最小费用

给你一个points 数组,表示 2D 平面上的一些点,其中 points[i] = [xi, yi] 。

连接点 [xi, yi] 和点 [xj, yj] 的费用为它们之间的 曼哈顿距离 :|xi - xj| + |yi - yj| ,其中 |val| 表示 val 的绝对值。

请你返回将所有点连接的最小总费用。只有任意两点之间 有且仅有 一条简单路径时,才认为所有点都已连接。

可以用 prim算法来解。

/*struct edge
{
    int from;
    int to;
    int cost;
};*/

//#define MAX_N   (500*999)
//struct edge g_ePool[1000][1000];

/*struct edgeInfo
{
    int offset;
    int size;
};

struct edgeInfo g_ei[1000];*/

struct vertex
{
    int id;
    int key;
};
struct vertex g_vertex[1000 * 1000];

int g_visit[1000];
int g_tc;


int g_minQ[1000* 1000];
int g_minQSize;

bool compare(int a, int b)
{
    return g_vertex[a].key < g_vertex[b].key;
}
void minQ_init()
{
    g_minQSize = 0;
}

void minQ_push(int v)
{
    int i = g_minQSize++;
    while(i > 0)
    {
        int pi = (i-1)/2;

        if(compare( g_minQ[pi], v) == true)
        {
            break;
        }

        g_minQ[i] = g_minQ[pi];
        i = pi;
    }

    g_minQ[i] = v;
}

int minQ_pop()
{
    //for(int i = 0; i < g_minQSize; ++i)
   // {
        //printf("^^^ %d  --> %d \n", g_vertex[g_minQ[i]].id, g_vertex[g_minQ[i]].key);
   // }
    int ret = g_minQ[0];
    int tmp = g_minQ[ --g_minQSize];

    int i = 0;
    while( 2 * i + 1 < g_minQSize )
    {
        int a = 2 * i + 1;
        int b = a + 1;
        if( b < g_minQSize && compare( g_minQ[b], g_minQ[a]))
        {
            a = b;
        }

        if( compare(tmp, g_minQ[a]))
        {
            break;
        }

        g_minQ[i] = g_minQ[a];
        i = a;
    }
    g_minQ[i] = tmp;
    return ret;
}

bool minQ_isEmpty(){return g_minQSize == 0;}

int abs(int i) { return i > 0 ? i : (-i);}

int minCostConnectPoints(int** points, int pointsSize, int* pointsColSize){

    ++g_tc;
   // int k = 0;
   // int offset = 0;
    //int f = 0;
  //  for(int i = 0; i < pointsSize; ++i)
   // {
       // for(int j = 0; j  < pointsSize; ++j)
        //{
          //  g_ePool[i][j].from = i;
           // g_ePool[i][j].to = j;
           // g_ePool[i][j].cost = abs(points[i][0] - points[j][0]) + 
           // abs(points[i][1] - points[j][1]);
           //  ++k;  
            
          //  ++k;
       // }
     //   g_ei[i].offset = offset;
     //   g_ei[i].size = pointsSize - (i+1);
     //   offset += pointsSize -(i+1);
       // ++f;
     //  printf("offset: %d, size: %d\n", g_ei[i].offset, g_ei[i].size);         
   // }
  // g_ei[pointsSize-1].size = 0;

   

    int m = 0;
    g_vertex[m].id = 0;
    g_vertex[m].key = 0;
    ++m;

    minQ_init();

    minQ_push(0);

    int ret = 0;
    int cnt = pointsSize;
    while( minQ_isEmpty() == false && cnt > 0)
    {
        int a = minQ_pop();
        int toId = g_vertex[a].id;
        int key = g_vertex[a].key;
        if( g_visit[toId] == g_tc)
        {
            continue;
        }
        
        g_visit[toId] = g_tc;
        --cnt;
        ret += key;
      //  printf("#### toId: %d, key: %d\n", toId, key);
     //   printf("## %d %d\n", g_ei[toId].offset,g_ei[toId].size );


        for(int i = 0; i < pointsSize; ++i)
        {
            if( i == toId)
            {
                continue;
            }

            int cost = abs(points[i][0] - points[toId][0]) + abs(points[i][1] - points[toId][1]);
           // int to = g_ePool[toId][i].to;
          //  int cost = g_ePool[toId][i].cost;

           // printf("to: %d, visit[%d]: %d\n", to, to, g_visit[to]);
            if( g_visit[i] == g_tc)
            {
                continue;
            }
            g_vertex[m].id = i;
            g_vertex[m].key = cost;
         //   printf("from: %d, to: %d, cost: %d\n", toId, to, cost);
            minQ_push(m);
            ++m;
        }
    }

    return ret;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值