📌  相关文章
📜  查找从源头开始的路径是否超过k个长度

📅  最后修改于: 2021-05-24 19:03:47             🧑  作者: Mango

给定一个图,图中的一个源顶点和一个数字k,请确定是否存在一条从给定源开始并在任何其他顶点处结束的简单路径(无周期)。

Example:
Input  : Source s = 0, k = 58
Output : True
There exists a simple path 0 -> 7 -> 1
-> 2 -> 8 -> 6 -> 5 -> 3 -> 4
Which has a total distance of 60 km which
is more than 58.

Input  : Source s = 0, k = 62
Output : False

In the above graph, the longest simple
path has distance 61 (0 -> 7 -> 1-> 2
 -> 3 -> 4 -> 5-> 6 -> 8, so output 
should be false for any input greater 
than 61.

强烈建议您最小化浏览器,然后自己尝试。
需要注意的重要一件事是,简单地执行BFS或DFS并在每个步骤中选择最长的边缘是行不通的。原因是,较短的边缘会由于较高的重量边缘连接而产生较长的路径。
这个想法是使用回溯。我们从给定的源开始,探索当前顶点的所有路径。我们跟踪到源的当前距离。如果距离大于k,则返回true。如果路径产生的距离不超过k,我们将回溯。
我们如何确保路径简单并且不会循环循环?这个想法是要跟踪数组中当前路径的顶点。每当我们将顶点添加到路径时,我们都会检查该顶点在当前路径中是否已经存在。如果存在,我们将忽略边缘。
以下是上述想法的实现。

C++
// Program to find if there is a simple path with
// weight more than k
#include
using namespace std;
  
// iPair ==>  Integer Pair
typedef pair iPair;
  
// This class represents a dipathted graph using
// adjacency list representation
class Graph
{
    int V;    // No. of vertices
  
    // In a weighted graph, we need to store vertex
    // and weight pair for every edge
    list< pair > *adj;
    bool pathMoreThanKUtil(int src, int k, vector &path);
  
public:
    Graph(int V);  // Constructor
  
    // function to add an edge to graph
    void addEdge(int u, int v, int w);
    bool pathMoreThanK(int src, int k);
};
  
// Returns true if graph has path more than k length
bool Graph::pathMoreThanK(int src, int k)
{
    // Create a path array with nothing included
    // in path
    vector path(V, false);
  
    // Add source vertex to path
    path[src] = 1;
  
    return pathMoreThanKUtil(src, k, path);
}
  
// Prints shortest paths from src to all other vertices
bool Graph::pathMoreThanKUtil(int src, int k, vector &path)
{
    // If k is 0 or negative, return true;
    if (k <= 0)
        return true;
  
    // Get all adjacent vertices of source vertex src and
    // recursively explore all paths from src.
    list::iterator i;
    for (i = adj[src].begin(); i != adj[src].end(); ++i)
    {
        // Get adjacent vertex and weight of edge
        int v = (*i).first;
        int w = (*i).second;
  
        // If vertex v is already there in path, then
        // there is a cycle (we ignore this edge)
        if (path[v] == true)
            continue;
  
        // If weight of is more than k, return true
        if (w >= k)
            return true;
  
        // Else add this vertex to path
        path[v] = true;
  
        // If this adjacent can provide a path longer
        // than k, return true.
        if (pathMoreThanKUtil(v, k-w, path))
            return true;
  
        // Backtrack
        path[v] = false;
    }
  
    // If no adjacent could produce longer path, return
    // false
    return false;
}
  
// Allocates memory for adjacency list
Graph::Graph(int V)
{
    this->V = V;
    adj = new list [V];
}
  
// Utility function to an edge (u, v) of weight w
void Graph::addEdge(int u, int v, int w)
{
    adj[u].push_back(make_pair(v, w));
    adj[v].push_back(make_pair(u, w));
}
  
// Driver program to test methods of graph class
int main()
{
    // create the graph given in above fugure
    int V = 9;
    Graph g(V);
  
    //  making above shown graph
    g.addEdge(0, 1, 4);
    g.addEdge(0, 7, 8);
    g.addEdge(1, 2, 8);
    g.addEdge(1, 7, 11);
    g.addEdge(2, 3, 7);
    g.addEdge(2, 8, 2);
    g.addEdge(2, 5, 4);
    g.addEdge(3, 4, 9);
    g.addEdge(3, 5, 14);
    g.addEdge(4, 5, 10);
    g.addEdge(5, 6, 2);
    g.addEdge(6, 7, 1);
    g.addEdge(6, 8, 6);
    g.addEdge(7, 8, 7);
  
    int src = 0;
    int k = 62;
    g.pathMoreThanK(src, k)? cout << "Yes\n" :
                             cout << "No\n";
  
    k = 60;
    g.pathMoreThanK(src, k)? cout << "Yes\n" :
                             cout << "No\n";
  
    return 0;
}


Java
// Java Program to find if there is a simple path with 
// weight more than k 
import java.util.*; 
public class GFG{ 
  
  static class AdjListNode { 
    int v; 
    int weight; 
  
    AdjListNode(int _v, int _w) 
    { 
      v = _v; 
      weight = _w; 
    } 
    int getV() { return v; } 
    int getWeight() { return weight; } 
  }
  
  // This class represents a dipathted graph using 
  // adjacency list representation 
  static class Graph 
  { 
    int V; // No. of vertices 
  
    // In a weighted graph, we need to store vertex 
    // and weight pair for every edge 
    ArrayList> adj; 
  
    // Allocates memory for adjacency list 
    Graph(int V) 
    { 
      this.V = V; 
      adj = new ArrayList>(V); 
  
      for(int i = 0; i < V; i++)
      {
        adj.add(new ArrayList());
      }
    } 
  
    // Utility function to an edge (u, v) of weight w 
    void addEdge(int u, int v, int weight) 
    { 
      AdjListNode node1 = new AdjListNode(v, weight); 
      adj.get(u).add(node1); // Add v to u's list 
  
      AdjListNode node2 = new AdjListNode(u, weight); 
      adj.get(v).add(node2); // Add u to v's list 
    } 
  
    // Returns true if graph has path more than k length 
    boolean pathMoreThanK(int src, int k) 
    { 
        
      // Create a path array with nothing included 
      // in path 
      boolean path[] = new boolean[V];
  
      Arrays.fill(path, false);
  
      // Add source vertex to path 
      path[src] = true; 
  
      return pathMoreThanKUtil(src, k, path); 
    } 
  
    // Prints shortest paths from src to all other vertices 
    boolean pathMoreThanKUtil(int src, int k, boolean[] path) 
    {  
        
      // If k is 0 or negative, return true; 
      if (k <= 0) 
        return true; 
  
      // Get all adjacent vertices of source vertex src and 
      // recursively explore all paths from src. 
      ArrayList it = adj.get(src);
  
      int index = 0;
      for(int i = 0; i < adj.get(src).size(); i++)
      { 
        AdjListNode vertex = adj.get(src).get(i);
  
        // Get adjacent vertex and weight of edge 
        int v = vertex.v; 
        int w = vertex.weight; 
  
        // increase theindex
        index++;
  
        // If vertex v is already there in path, then 
        // there is a cycle (we ignore this edge) 
        if (path[v] == true) 
          continue; 
  
        // If weight of is more than k, return true 
        if (w >= k) 
          return true; 
  
        // Else add this vertex to path 
        path[v] = true; 
  
        // If this adjacent can provide a path longer 
        // than k, return true. 
        if (pathMoreThanKUtil(v, k-w, path)) 
          return true; 
  
        // Backtrack 
        path[v] = false; 
      } 
  
      // If no adjacent could produce longer path, return 
      // false 
      return false; 
    } 
  
  }
  
  // Driver program to test methods of graph class 
  public static void main(String[] args) 
  { 
      
    // create the graph given in above fugure 
    int V = 9; 
    Graph g = new Graph(V); 
  
    // making above shown graph 
    g.addEdge(0, 1, 4); 
    g.addEdge(0, 7, 8); 
    g.addEdge(1, 2, 8); 
    g.addEdge(1, 7, 11); 
    g.addEdge(2, 3, 7); 
    g.addEdge(2, 8, 2); 
    g.addEdge(2, 5, 4); 
    g.addEdge(3, 4, 9); 
    g.addEdge(3, 5, 14); 
    g.addEdge(4, 5, 10); 
    g.addEdge(5, 6, 2); 
    g.addEdge(6, 7, 1); 
    g.addEdge(6, 8, 6); 
    g.addEdge(7, 8, 7); 
  
    int src = 0; 
    int k = 62; 
  
    if(g.pathMoreThanK(src, k))
      System.out.println("YES");
    else
      System.out.println("NO");
  
  
    k = 60; 
    if(g.pathMoreThanK(src, k))
      System.out.println("YES");
    else
      System.out.println("NO");
  
  } 
}
  
// This code is contributed by adityapande88.


Python3
# Program to find if there is a simple path with 
# weight more than k 
    
# This class represents a dipathted graph using 
# adjacency list representation 
class Graph:
    # Allocates memory for adjacency list 
    def __init__(self, V):
        self.V = V 
        self.adj = [[] for i in range(V)]
    
    # Returns true if graph has path more than k length 
    def pathMoreThanK(self,src, k):
        # Create a path array with nothing included 
        # in path 
        path = [False]*self.V 
        
        # Add source vertex to path 
        path[src] = 1 
        
        return self.pathMoreThanKUtil(src, k, path)
        
    # Prints shortest paths from src to all other vertices 
    def pathMoreThanKUtil(self,src, k, path):
        # If k is 0 or negative, return true 
        if (k <= 0): 
            return True 
        
        # Get all adjacent vertices of source vertex src and 
        # recursively explore all paths from src.
        i = 0
        while i != len(self.adj[src]):
            # Get adjacent vertex and weight of edge 
            v = self.adj[src][i][0]
            w = self.adj[src][i][1]
            i += 1
        
            # If vertex v is already there in path, then 
            # there is a cycle (we ignore this edge) 
            if (path[v] == True): 
                continue 
        
            # If weight of is more than k, return true 
            if (w >= k):
                return True 
        
            # Else add this vertex to path 
            path[v] = True 
        
            # If this adjacent can provide a path longer 
            # than k, return true. 
            if (self.pathMoreThanKUtil(v, k-w, path)): 
                return True 
        
            # Backtrack 
            path[v] = False
        
        # If no adjacent could produce longer path, return 
        # false 
        return False 
       
    # Utility function to an edge (u, v) of weight w 
    def addEdge(self,u, v, w):
        self.adj[u].append([v, w]) 
        self.adj[v].append([u, w])
    
# Driver program to test methods of graph class 
if __name__ == '__main__':
   
    # create the graph given in above fugure 
    V = 9 
    g = Graph(V) 
    
    #  making above shown graph 
    g.addEdge(0, 1, 4) 
    g.addEdge(0, 7, 8) 
    g.addEdge(1, 2, 8) 
    g.addEdge(1, 7, 11) 
    g.addEdge(2, 3, 7) 
    g.addEdge(2, 8, 2) 
    g.addEdge(2, 5, 4) 
    g.addEdge(3, 4, 9) 
    g.addEdge(3, 5, 14) 
    g.addEdge(4, 5, 10) 
    g.addEdge(5, 6, 2) 
    g.addEdge(6, 7, 1) 
    g.addEdge(6, 8, 6) 
    g.addEdge(7, 8, 7) 
    
    src = 0 
    k = 62 
    if g.pathMoreThanK(src, k):
        print("Yes")
    else:
        print("No") 
    
    k = 60 
    if g.pathMoreThanK(src, k):
        print("Yes") 
    else:
        print("No")


输出:

No
Yes