给你一个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;
}