📜  具有最小边乘积且权重 > 0 的路径

📅  最后修改于: 2021-09-22 10:03:20             🧑  作者: Mango

给定一个有N 个节点和E 条边的有向图,其中每条边的权重> 0 ,还给定一个源S和一个目的地D 。任务是找到从SD的边乘积最小的路径。如果没有从SD 的路径,则打印-1

例子:

方法:想法是使用bellman Ford算法。这是因为这里不能使用 Dijkstra 算法,因为它只适用于非负边。这是因为在乘以 [0-1) 之间的值时,乘积会无限减少,最终返回 0。
此外,需要检测循环,因为如果存在循环,则该循环的乘积将无限期地将乘积减少到 0,并且乘积将趋向于 0。为了简单起见,我们将报告此类循环。
可以按照以下步骤计算结果:

  1. 初始化一个数组, dis[] ,初始值为“inf”,dis[S] 为 1。
  2. 从 1 – N-1 运行一个循环。对于图中的每条边:
    • dis[edge.second] = min(dis[edge.second], dis[edge.first]*weight(edge))
  3. 对图中的每条边运行另一个循环,如果任何边以 (dis[edge.second] > dis[edge.first]*weight(edge)) 退出,则检测到循环。
  4. 如果 dist[d] 在无穷大,返回-1 ,否则返回dist[d]

下面是上述方法的实现:

C++
// C++ implementation of the approach.
#include 
using namespace std;
 
double inf = std::
    numeric_limits::infinity();
 
// Function to return the smallest
// product of edges
double bellman(int s, int d,
               vector,
                           double> >
                   ed,
               int n)
{
    // If the source is equal
    // to the destination
    if (s == d)
        return 0;
 
    // Array to store distances
    double dis[n + 1];
 
    // Initialising the array
    for (int i = 1; i <= n; i++)
        dis[i] = inf;
    dis[s] = 1;
 
    // Bellman ford algorithm
    for (int i = 0; i < n - 1; i++)
        for (auto it : ed)
            dis[it.first.second] = min(dis[it.first.second],
                                       dis[it.first.first]
                                           * it.second);
 
    // Loop to detect cycle
    for (auto it : ed) {
        if (dis[it.first.second]
            > dis[it.first.first] * it.second)
            return -2;
    }
 
    // Returning final answer
    if (dis[d] == inf)
        return -1;
    else
        return dis[d];
}
 
// Driver code
int main()
{
 
    int n = 3;
    vector, double> > ed;
 
    // Input edges
    ed = { { { 1, 2 }, 0.5 },
           { { 1, 3 }, 1.9 },
           { { 2, 3 }, 3 } };
 
    // Source and Destination
    int s = 1, d = 3;
 
    // Bellman ford
    double get = bellman(s, d, ed, n);
 
    if (get == -2)
        cout << "Cycle Detected";
    else
        cout << get;
}


Java
// Java implementation of the approach
import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
 
class Pair
{
    K first;
    V second;
 
    public Pair(K first, V second)
    {
        this.first = first;
        this.second = second;
    }
}
 
class GFG{
 
static final float inf = Float.POSITIVE_INFINITY;
 
// Function to return the smallest
// product of edges
static float bellman(int s, int d,
                     ArrayList, Float>> ed,
                     int n)
{
     
    // If the source is equal
    // to the destination
    if (s == d)
        return 0;
 
    // Array to store distances
    float[] dis = new float[n + 1];
 
    // Initialising the array
    Arrays.fill(dis, inf);
    dis[s] = 1;
 
    // Bellman ford algorithm
    for(int i = 0; i < n - 1; i++)
        for(Pair, Float> it : ed)
            dis[it.first.second] = Math.min(dis[it.first.second],
                                            dis[it.first.first] *
                                                it.second);
 
    // Loop to detect cycle
    for(Pair, Float> it : ed)
    {
        if (dis[it.first.second] >
            dis[it.first.first] *
                it.second)
            return -2;
    }
 
    // Returning final answer
    if (dis[d] == inf)
        return -1;
    else
        return dis[d];
}
 
// Driver code
public static void main(String[] args)
{
    int n = 3;
     
    // Input edges
    ArrayList, Float>> ed = new ArrayList<>(
            Arrays.asList(
                      new Pair, Float>(
                           new Pair(1, 2), 0.5f),
                    new Pair, Float>(
                         new Pair(1, 3), 1.9f),
                    new Pair, Float>(
                         new Pair(2, 3), 3f)));
 
    // Source and Destination
    int s = 1, d = 3;
 
    // Bellman ford
    float get = bellman(s, d, ed, n);
 
    if (get == -2)
        System.out.println("Cycle Detected");
    else
        System.out.println(get);
}
}
 
// This code is contributed by sanjeev2552


Python3
# Python3 implementation of the approach.
import sys
 
inf = sys.maxsize;
 
# Function to return the smallest
# product of edges
def bellman(s, d, ed, n) :
 
    # If the source is equal
    # to the destination
    if (s == d) :
        return 0;
 
    # Array to store distances
    dis = [0]*(n + 1);
 
    # Initialising the array
    for i in range(1, n + 1) :
        dis[i] = inf;
         
    dis[s] = 1;
 
    # Bellman ford algorithm
    for i in range(n - 1) :
        for it in ed :
            dis[it[1]] = min(dis[it[1]], dis[it[0]] * ed[it]);
 
    # Loop to detect cycle
    for it in ed :
        if (dis[it[1]] > dis[it[0]] * ed[it]) :
            return -2;
 
    # Returning final answer
    if (dis[d] == inf) :
        return -1;
    else :
        return dis[d];
 
# Driver code
if __name__ == "__main__" :
 
    n = 3;
     
    # Input edges
    ed = { ( 1, 2 ) : 0.5 ,
        ( 1, 3 ) : 1.9 ,
        ( 2, 3 ) : 3 };
 
    # Source and Destination
    s = 1; d = 3;
 
    # Bellman ford
    get = bellman(s, d, ed, n);
 
    if (get == -2) :
        print("Cycle Detected");
    else :
        print(get);
 
# This code is contributed by AnkitRai01


Javascript


输出:
1.5

时间复杂度: O(E*V)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程