用java语言解决 最小权顶点覆盖问题 要求:数据输入:第一行有2个正整数n和m,表示给定的图G有n个顶点和m条边。 数据输出:将计算的最小权顶点覆盖的顶点权之和以及最优解输出
时间: 2023-07-14 11:13:21 浏览: 100
以下是用Java语言解决最小权顶点覆盖问题的代码:
```java
import java.util.Scanner;
public class MinimumWeightVertexCover {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); // 顶点数量
int m = sc.nextInt(); // 边数量
int[] weight = new int[n+1]; // 存储每个顶点的权值
for (int i = 1; i <= n; i++) {
weight[i] = sc.nextInt();
}
int[][] graph = new int[n+1][n+1]; // 存储图的邻接矩阵
for (int i = 0; i < m; i++) {
int u = sc.nextInt();
int v = sc.nextInt();
graph[u][v] = 1;
graph[v][u] = 1;
}
int ans = minimumWeightVertexCover(n, graph, weight); // 求解最小权顶点覆盖问题
System.out.println("最小权顶点覆盖的顶点权之和为:" + ans);
}
// 求解最小权顶点覆盖问题
private static int minimumWeightVertexCover(int n, int[][] graph, int[] weight) {
int ans = 0;
int[] match = new int[n+1];
boolean[] vis = new boolean[n+1];
for (int i = 1; i <= n; i++) {
match[i] = -1;
}
for (int i = 1; i <= n; i++) {
if (match[i] == -1) {
for (int j = 1; j <= n; j++) {
vis[j] = false;
}
if (dfs(i, graph, weight, match, vis)) {
ans += weight[i];
}
}
}
return ans;
}
// 使用深度优先搜索求解最小权顶点覆盖问题
private static boolean dfs(int u, int[][] graph, int[] weight, int[] match, boolean[] vis) {
vis[u] = true;
for (int v = 1; v < graph[u].length; v++) {
if (graph[u][v] == 1 && !vis[v]) {
vis[v] = true;
if (match[v] == -1 || dfs(match[v], graph, weight, match, vis)) {
match[v] = u;
return true;
}
}
}
return false;
}
}
```
在上述代码中,我们使用深度优先搜索来求解最小权顶点覆盖问题。我们首先定义一个 `dfs` 函数来进行搜索。在搜索过程中,我们对于每一个未匹配的顶点 `u`,遍历其所有邻居顶点 `v`,如果当前邻居顶点 `v` 未被匹配,或者已被匹配但是可以通过其它路径更新匹配关系,我们就将顶点 `u` 和顶点 `v` 进行匹配,并且递归搜索顶点 `match[v]`。如果搜索成功,我们就返回 `true`,否则返回 `false`。
在主函数中,我们首先读入输入数据,然后调用 `minimumWeightVertexCover` 函数来求解最小权顶点覆盖问题。在此函数中,我们首先初始化匹配数组 `match`,然后对于每一个未匹配的顶点 `i`,我们使用 `dfs` 函数来尝试为其找到一个匹配顶点。如果搜索成功,我们就将该顶点的权值加入到结果中。最终,我们返回结果即可。
需要注意的是,在本题中,顶点的编号从 $1$ 开始。
阅读全文