Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 给定一棵树,为每条边指定权重,以最小化树中每条路径(u,v)的权重_Java_Algorithm_Tree - Fatal编程技术网

Java 给定一棵树,为每条边指定权重,以最小化树中每条路径(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,但问题上下文中的实际权重为零。同样,这个问题中树的根是

给定一棵树,为每条边指定权重,以最小化树中每条路径u、v的权重。为了澄清,我们正在最小化树中每条路径上的最大权重

这个问题可以用某种数据结构或算法来解决吗?如何确定要在树的每条边上放置哪些权重?输入是一个数字N,您必须在树的每一条边上的[0,N-2]值之间放置权重

让我澄清这个问题。假设你有一条边1,2,你在边上放置了权重3。在问题的上下文中,权重的实际定义是[0,N-2]中的最小最大值,该值不存在于u,v的路径上。即使特定边缘上的权重为3,但问题上下文中的实际权重为零。同样,这个问题中树的根是1

对于这个问题,我最初的方法是将[0,N-2]中的值(我们可以分配给每个边的边值)添加到堆栈中,然后使用DFS遍历树,从堆栈中弹出一个值(最大最边值),并将其分配给边。然而,这并不能使所有路径的成本最小化。请记住,成本是u,v路径上不存在的最小最大值。我们正试图在每一条可能的道路上降低成本

我的代码:

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。