【发布时间】:2019-08-13 01:38:46
【问题描述】:
我需要一些帮助来解决联合查找问题。
这是问题。
有一个无向连通图,其中 n 个节点标记为 1..n。但 一些边缘已断开连接图。找出 修复边缘的最小成本,以便所有节点再次 可以互相访问。
输入:
n,一个 int,表示节点的总数。
边缘,列表 表示由一条边连接的节点的整数对。
edgeToRepair,一个列表,其中每个元素都是一个三元组,表示 边缘当前断开的节点对和成本 分别重复那个边缘
(例如 [1, 2, 12] 表示重复 节点 1 和 2 之间的一条边,则成本为 12)。示例 1:
输入:n = 5,边 = [[1, 2], [2, 3], [3, 4], [4, 5], [1, 5]],
edgeToRepair = [[1, 2, 12], [3, 4, 30], [1, 5, 8]]输出:20
由于断边有 3 个连通分量: [1]、[2, 3] 和 [4, 5]。我们可以将这些组件连接成一个 通过重复节点 1 和 2 以及节点 1 之间的边来组成 和 5 最低成本 12 + 8 = 20。
public int minCostRepairEdges(int N, int[][] edges, int[][] edgesToRepair){
int[] unionFind = new int[N+1];
int totalEdges=0;
for(int[] edge : edges){
int ua = edge[0]; //node1
int ub = edge[1]; //node2
unionFind[ua] = ub;
totalEdges++;
}
//change unionFind for some broken edge
for(int[] broken : edgesToRepair){
int ua = Find(unionFind, broken[0]);
int ub = Find(unionFind, broken[1]);
if(ua == ub){
unionFind[ua] = 0;
}
}
Arrays.sort(edgesToRepair, (a,b)->(a[2]-b[2]));
int cost=0;
for(int[] i : edgesToRepair){
int ua = Find(unionFind, i[0]);
int ub = Find(unionFind, i[1]);
if(ua != ub){
unionFind[ua] = ub;
cost += i[2];
totalEdges++;
}
}
return edgesToRepair==N-1 ? cost : -1;
}
public int find(int[] uf, int find){
if(uf[find]==0) return find;
uf[find] = find(uf, uf[find]);
return uf[find];
}
到目前为止,上面是我的代码。
我的想法是
首先将所有边(给定的边[][])添加到 UnionFind,然后根据给定的边修复信息更新它。 (如果边缘被破坏,那么将在 union -find 中更新它)
然后尝试做基本的联合查找算法以最小的成本连接两个节点。
这里有什么错误的方法吗?
首先,当 unionFind 损坏时,我无法更新它。
我不知道如何处理两个节点之间的完整边缘。
任何建议都会有所帮助。
【问题讨论】:
标签: algorithm union-find