所以我要做的就是从二维数组(称为G)中实现Kruskal算法,如下所示:
0 0 0 0 0 12 13 0
0 0 6 0 0 0 0 3
0 6 0 4 0 0 0 5
0 0 4 0 10 0 0 7
0 0 0 10 0 11 8 9
12 0 0 0 11 0 1 0
13 0 0 0 8 1 0 2
0 3 5 7 9 0 2 0
0表示没有边连接这两个顶点,值表示边连接两个顶点,其中值表示边的权重,行和列是两个顶点它&#39连接。因此,12将连接0和5.所以我决定做的是找到数组中的最小元素,然后将其添加到另一个2d数组(H),其大小与G相同,但所有值都为0然后我检查并查看是否添加该边缘形成一个循环,如果是,那么我从H移除边缘并继续前进,直到每一行都被填满。这就是我的所作所为:
int numVerts = G.length;
int [][] H = new int[numVerts][numVerts];
int minWeight;
int k = 0;
int l = 0;
int boolcount = 0;
boolean [] R = new boolean[G.length];
Arrays.fill(R, false);
while (boolcount != numVerts){
for (int i = 0; i < numVerts; i++){
for (int j = 0; j < numVerts; j++){
if ((G[i][j] != 0) && (G[i][j] < minWeight)){
minWeight = G[i][j];
k = i;
l = j;
}
}
}
H[k][l] = minWeight;
H[l][k] = minWeight;
G[k][l] = 0;
G[l][k] = 0;
if (/*it forms a cycle*/){
H[k][l] = 0;
H[l][k] = 0;
} else {
//keep the edge
}
所以我现在唯一要弄清楚的是如何检查边缘是否与H中的任何其他边形成一个循环。根据数组如何在2d数组中表示,我可以弄清楚是否边缘形成周期?我想的一种方法是使用union-find来说明新添加的边缘是否在联合中,因为其他边缘然后不添加它,因为它创建了一个循环,但我在实现它时遇到了麻烦。
P.S:我还没有发布代码,因为当我决定保持优势的时候,但基本上是我在确定何时停止遍历时更新boolcount的地方。答案 0 :(得分:0)
选择一个起始顶点。首先遍历图宽度,同时在通过它们时否定边权重。如果遇到一个权重<0的边,那么你就有了一个循环图。