Java 给定一棵树,为每条边指定权重,以最小化树中每条路径(u,v)的权重
给定一棵树,为每条边指定权重,以最小化树中每条路径u、v的权重。为了澄清,我们正在最小化树中每条路径上的最大权重 这个问题可以用某种数据结构或算法来解决吗?如何确定要在树的每条边上放置哪些权重?输入是一个数字N,您必须在树的每一条边上的[0,N-2]值之间放置权重 让我澄清这个问题。假设你有一条边1,2,你在边上放置了权重3。在问题的上下文中,权重的实际定义是[0,N-2]中的最小最大值,该值不存在于u,v的路径上。即使特定边缘上的权重为3,但问题上下文中的实际权重为零。同样,这个问题中树的根是1 对于这个问题,我最初的方法是将[0,N-2]中的值(我们可以分配给每个边的边值)添加到堆栈中,然后使用DFS遍历树,从堆栈中弹出一个值(最大最边值),并将其分配给边。然而,这并不能使所有路径的成本最小化。请记住,成本是u,v路径上不存在的最小最大值。我们正试图在每一条可能的道路上降低成本 我的代码:Java 给定一棵树,为每条边指定权重,以最小化树中每条路径(u,v)的权重,java,algorithm,tree,Java,Algorithm,Tree,给定一棵树,为每条边指定权重,以最小化树中每条路径u、v的权重。为了澄清,我们正在最小化树中每条路径上的最大权重 这个问题可以用某种数据结构或算法来解决吗?如何确定要在树的每条边上放置哪些权重?输入是一个数字N,您必须在树的每一条边上的[0,N-2]值之间放置权重 让我澄清这个问题。假设你有一条边1,2,你在边上放置了权重3。在问题的上下文中,权重的实际定义是[0,N-2]中的最小最大值,该值不存在于u,v的路径上。即使特定边缘上的权重为3,但问题上下文中的实际权重为零。同样,这个问题中树的根是
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Stack;
import java.util.Iterator;
import java.util.ArrayList;
public class Mex {
public static void main (String [] args) throws IOException {
BufferedReader b1 = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(b1.readLine());
LinkedList<Integer>[] adj = new LinkedList[n+1];
ArrayList<Integer> v = new ArrayList<Integer>(n+1);
for(int i = 1; i<=n; i++) {
adj[i] = new LinkedList<Integer>();
}
for(int i = 0; i<n-1; i++) {
String [] edge = (b1.readLine()).split(" ");
adj[Integer.parseInt(edge[0])].add(Integer.parseInt(edge[1]));
adj[Integer.parseInt(edge[1])].add(Integer.parseInt(edge[0]));
v.add(Integer.parseInt(edge[0]));
v.add(Integer.parseInt(edge[1]));
}
dfs(adj, 1, n, v);
}
static void dfs(LinkedList<Integer> adj[], int u, int n, ArrayList<Integer> order) {
Stack<Integer> values = new Stack<>();
int [][] weight = new int[n+1][n+1];
for(int i = 0; i<n-1; i++) {
values.push(i);
}
boolean [] visited = new boolean[n+1];
int [] parent = new int[n+1];
for (int i = 1; i < n+1; i++)
visited[i] = false;
Stack<Integer> stack = new Stack<>();
stack.push(u);
while(stack.empty() == false) {
u = stack.peek();
stack.pop();
if(visited[u] == false) {
visited[u] = true;
if(u!= 1) {
if(adj[u].size()==1) {
if(values.contains(0)) {
weight[parent[u]][u] = 0;
values.remove(0);
}
else {
int w = values.pop();
weight[parent[u]][u] = w;
}
}
else {
int w = values.pop();
weight[parent[u]][u] = w;
}
}
}
Iterator<Integer> itr = adj[u].iterator();
while (itr.hasNext()) {
int v = itr.next();
if(parent[v]==0 && v!=1) {
parent[v] = u;
}
if(!visited[v])
stack.push(v);
}
}
for(int i = 0; i<order.size()-1; i+=2) {
if(parent[order.get(i)]==order.get(i+1)) {
System.out.println(weight[order.get(i+1)][order.get(i)]);
}
else {
System.out.println(weight[order.get(i)][order.get(i+1)]);
}
}
}
}
解决这个问题不需要特殊的算法或数据结构。您只需要做一个关键观察: 如果图形中的每个顶点的阶数小于等于2,则无论如何放置顶点,始终存在一条与每条边接触的路径。因此,如何放置标签并不重要 如果图中至少有一个顶点的阶数为3或更高,则可以将标签0、1和2放置在与公共顶点相关的边上。现在,最大最小排他项是2,因为我们可以选择从0到1的路径。很明显,你不可能做得比这更好,因为你总是可以从0开始,然后到1得到最小排他值2。因此,可以使边0、1和2与同一顶点关联。其他标签不重要
我想你可能把这个问题的措辞弄错了。从您的问题的措辞以及Java类MEX的名称来看,这意味着最小排他性,我很确定您是从CodeForces:讨论这个问题的。如果这是你所指的问题,那么你在文章中遗漏了一些重要的细节。如果这是你正在谈论的问题,请告诉我,我可以向你解释解决方案。这确实是我正在问的问题。如果你能给我解释一下,那就太好了。如果图中的每个顶点的阶数都小于等于2,那么MEX是1吗?不,如果每个顶点的阶数都小于等于2,那么MEX等于顶点数减去1。为什么?因为你总能找到一条接触每一条边的路。所以最小排他项是下一个正数,即N-1。