最近我在树上读到了一个问题但我发现很难解决这个问题。这是问题:
有 n个城市(2到10 ^ 5)和(n-1)双向道路的国家,可以在任何一对之间旅行城市。我们有 1魔术卡车可以在城市之间旅行但是需要 1个单位时间(如果它已加载)和 0单位时间(如果没有加载)< / strong>在相邻城市之间旅行,最多可以保留1个产品单元。
现在,您可以在任何城市拥有正好2个产品单元的客户,并且不能等待超过2个单位的时间。
现在的问题是,我们必须尽量减少存储总数,并给出限制:
在国家/地区分配存储空间,以便您可以按时填写至少第一个订单。鉴于订单可以放在任何城市。
时间限制:1秒
我尝试了什么:
我认为最糟糕的做法是蛮力。尝试在每个城市放置存储(2 ^ n种可能性)并检查是否可以在邻近城市的帮助下完成每个城市秩序。但是时间复杂度将是(n * 2 ^ n)。所以根本不会起作用。
我想的第二种方法是以某种方式在树上使用DP。而且我也不确定这是否是最优的。从上面的问题我可以确保叶子肯定有1个存储。我在想DP,从root开始检查孩子是否可以帮助完成它的顺序并相应地为该城市分配存储,有叶子的基础案例。但问题在于,孩子们也可以从父母那里完成订单,所以它正在制作循环循环。所以,它也没有帮助我。
我最后的方法是考虑在答案本身上应用二进制搜索。由于答案可以介于(1,n)之间,因此可以在nLog(n)顺序中找到答案。但问题是,我无法想到在具有特定存储空间的城市中分配存储的最佳方式。
所以,就是这样..我努力但却无法解决这个问题。任何帮助,将不胜感激。 :)
注意:我不知道为什么他们这样复杂的问题陈述如此复杂。他们可以用更简单的方式轻松解释问题。结果我再也找不到网络上的这个问题了。我想这是代码系统的某个地方。
答案 0 :(得分:4)
关于图表需要注意的重要事项是,有n个城市和n-1条道路,所有城市都可以到达;这意味着:
每个城市都有两种可能性;要么:
这也意味着一个单独连接的城市(道路的终点)总是有一个存储设施,一串双重连接的城市应该(最佳地)交替地拥有一个存储设施,这将给我们决定储存设施放置位置的起点。
blue:当前节点;绿色:存储;橙色:没有储存; +:需要另一个带存储的邻居; ?:已访问但尚未解决
这为我们提供了以下算法:
这基本上是“沿着所有道路行进并且再次回溯”算法,因此被访问节点的数量是2×N并且复杂度是线性的或O(N)。
值得注意的是,访问城市的顺序不会改变结果,即存储设施的数量,但可能会改变其部分位置。考虑4个城市的这两个解决方案:
S - / - S - S (solved left to right)
S - S - / - S (solved right to left)
靠近实际代码,让我们看看一旦确定了终点后该怎么做。该图由例如节点组成。这个:
NODE "city" C1
- neighbours: [C2, C4, C7]
- has_storage: undefined <- at first; will be set to true/false
- needs_more_storage: true/false <- we'll add this property as we go
- visited: true/false <- we'll add this property as we go
我们从一个终点开始,然后对于每个节点,我们将: