在一个城市中,有
n
个人,每个人在 城市。 (如果a是b的朋友,那么b也是a的朋友)我们想在这些人之间散布谣言,但要说 每个人的传言都有代价c_i
,但此后,这个人 免费在所有朋友之间散布谣言。我们希望找到最低成本,以将谣言传播给所有 市。在输入中,我们得到
n
:人数。m
:关系数。然后是n
整数c_i
:向人i
说谣言的费用,然后在m
行中,我们得到两个整数u
,v
在表示u,v
是朋友的每一行中。 (请注意,人数从1
到n
,但在数组中,人数从0
到n-1
)也
n,m<=10E5
和c_i<=10E9
我认为这个问题等同于无向图的所有连接组件中的最小元素之和。
我在使用C ++的Internet中找到了解决方案,但是我想用Java编写它,因此在下面使用dfs编写了程序。问题是,当我将答案提交给发现问题的站点中的在线法官时,它仅通过了20个测试中的3个。我想知道我的解决方案的哪一部分是错误的?
(该网站不是英语,实际上是大学的在线法官系统,但如果您愿意,我可以链接到该网站)
最终代码完全可以正常工作:
import java.util.LinkedList;
import java.util.Scanner;
class Graph {
int numberOfVertices;
LinkedList<Integer>[] graph;
boolean[] visited;
long[] costs;
Graph(int numberOfVertices,long[] costs) {
this.numberOfVertices = numberOfVertices;
this.graph = new LinkedList[numberOfVertices];
for (int v = 0; v < numberOfVertices; v++) {
graph[v] = new LinkedList<Integer>();
}
this.costs=costs;
this.visited = new boolean[numberOfVertices];
}
void addEdge(int u, int v) {
graph[u].add(v);
graph[v].add(u);
}
long dfs(int node, long mini) {
// Stores the minimum
mini = Math.min(mini, costs[ node]);
// Marks node as visited
visited[ node] = true;
// Traversed in all the connected nodes
for (int i : graph[ node]) {
if (!visited[ i])
mini = dfs(i, mini);
}
return mini;
}
void minimumSumConnectedComponents() {
// Initially sum is 0
long sum = 0L;
// Traverse for all nodes
for (int i = 0; i < numberOfVertices; i++) {
if (!visited[i]) {
sum += dfs(i, costs[i]);
}
}
// Returns the answer
System.out.println(sum);
}
}
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int numberOfVertices,numberOfRelations;
numberOfVertices=input.nextInt();
numberOfRelations=input.nextInt();
long [] costs = new long[numberOfVertices];
for (int i =0;i<numberOfVertices;i++)
{
costs[i]=input.nextLong();
}
Graph g = new Graph(numberOfVertices,costs);
for (int i =0;i<numberOfRelations;i++)
{
int v1,v2;
v1=input.nextInt();
v2=input.nextInt();
g.addEdge(v1-1,v2-1);
}
g.minimumSumConnectedComponents();
}
}
旧代码存在一些问题:
import java.util.Scanner;
import java.util.Vector;
class Graph {
Integer numberOfVertices;
Vector<Integer>[] graph;
boolean[] visited;
Long[] costs;
Graph(Integer numberOfVertices,Long[] costs) {
this.numberOfVertices = numberOfVertices;
this.graph = new Vector[numberOfVertices];
for (Integer v = 0; v < numberOfVertices; v++) {
graph[v] = new Vector<Integer>();
}
this.costs = new Long[numberOfVertices];
for (Integer v = 0; v < numberOfVertices; v++) {
this.costs[v] = costs[v];
}
this.visited = new boolean[numberOfVertices];
}
void addEdge(Integer u, Integer v) {
graph[u].add(v);
graph[v].add(u);
}
void dfs(Integer node, Long mini) {
// Stores the minimum
mini = Math.min(mini, costs[(Integer) node]);
// Marks node as visited
visited[(Integer) node] = true;
// Traversed in all the connected nodes
for (Integer i : graph[(Integer) node]) {
if (!visited[(Integer) i])
dfs(i, mini);
}
}
void minimumSumConnectedComponents() {
// Initially sum is 0
Long sum = 0L;
// Traverse for all nodes
for (Integer i = 0; i < numberOfVertices; i++) {
if (!visited[i]) {
Long mini = costs[i];
dfs(i, mini);
sum += mini;
}
}
// Returns the answer
System.out.println(sum);
}
}
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Integer numberOfVertices,numberOfRelations;
numberOfVertices=input.nextInt();
numberOfRelations=input.nextInt();
Long [] costs = new Long[numberOfVertices];
for (Integer i =0;i<numberOfVertices;i++)
{
costs[i]=input.nextLong();
}
Graph g = new Graph(numberOfVertices,costs);
for (Integer i =0;i<numberOfRelations;i++)
{
Integer v1,v2;
v1=input.nextInt();
v2=input.nextInt();
g.addEdge(v1-1,v2-1);
}
g.minimumSumConnectedComponents();
}
}
测试用例:
5 2
2 5 3 4 8
1 4
4 5
Expected Output: 10
10 0
1 2 3 4 5 6 7 8 9 10
Expected Output: 55
10 5
1 6 2 7 3 8 4 9 5 10
1 2
3 4
5 6
7 8
9 10
Expected Output: 15
我的程序通过了此示例测试用例,但对于许多未知的测试用例却给出了错误的答案。
答案 0 :(得分:2)
这些行不能满足您的要求:
// Stores the minimum
mini = Math.min(mini, costs[(Integer) node]);
如果他们改变了调用者的mini
,那么您的代码看起来是正确的(假设没有堆栈溢出)。我的建议是返回mini
的新值供调用者使用:
Long dfs(Integer node, Long mini) {
// Stores the minimum
mini = Math.min(mini, costs[(Integer) node]);
// Marks node as visited
visited[(Integer) node] = true;
// Traversed in all the connected nodes
for (Integer i : graph[(Integer) node]) {
if (!visited[(Integer) i])
mini = dfs(i, mini);
}
return mini;
}
void minimumSumConnectedComponents() {
// Initially sum is 0
Long sum = 0L;
// Traverse for all nodes
for (Integer i = 0; i < numberOfVertices; i++) {
if (!visited[i]) {
sum += dfs(i, costs[i]);
}
}
// Returns the answer
System.out.println(sum);
}