แนวคิด
ในส่วนที่เกี่ยวกับกราฟที่กำหนด จุดยอดต้นทางในกราฟและตัวเลข k (ในที่นี้ k จะระบุความยาวของเส้นทางของกราฟระหว่างจุดยอดต้นทางและจุดยอดปลายทาง) หน้าที่ของเราคือตรวจสอบว่ามีจุดเริ่มต้นอย่างง่าย (ไม่มีวงจร) หรือไม่ จากต้นทางที่กำหนดและสิ้นสุดที่จุดยอดอื่นใด (เช่น ปลายทาง) กราฟแสดงดังต่อไปนี้ -

อินพุต
Source s = 0, k = 64
ผลลัพธ์
True
มีเส้นทางง่ายๆ 0 -> 7 -> 1-> 2 -> 8 -> 6 -> 5 -> 3 -> 4 ซึ่งมีระยะทางรวม 68 กม. ซึ่งมากกว่า 64
อินพุต
Source s = 0, k = 70
ผลลัพธ์
False
ในกราฟด้านบน เส้นทางที่ง่ายที่สุดที่ยาวที่สุดคือระยะทาง 69 (0 -> 7 -> 1-> 2 -> 3 -> 4 -> 5-> 6 -> 8 ดังนั้นเอาต์พุตควรเป็นเท็จสำหรับอินพุตใดๆ ที่มากกว่า 69
วิธีการ
ควรสังเกตว่าสิ่งสำคัญอย่างหนึ่งคือเพียงแค่ดำเนินการ BFS(Breadth First Search) หรือ DFS(Depth First Search) และการเลือกขอบที่ยาวที่สุดในทุกขั้นตอนจะไม่ทำงาน เหตุผลเบื้องหลังขอบที่สั้นกว่าสามารถสร้างเส้นทางที่ยาวขึ้นได้เนื่องจาก ขอบน้ำหนักที่สูงขึ้นเชื่อมต่อผ่านมัน
ตอนนี้แนวคิดคือการนำ Backtracking มาใช้ ในกรณีนี้ เราเริ่มต้นจากแหล่งที่กำหนด ข้ามทุกวิถีทางจากจุดยอดปัจจุบัน ที่นี่ เราติดตามระยะทางปัจจุบันจากแหล่งที่มา จะเห็นได้ว่าถ้าระยะทางมากกว่า k เราคืนค่าเป็นจริง แต่ในกรณีทางเลือกอื่นเพื่อที่ว่าถ้าเส้นทางไม่ได้สร้างระยะทางเกิน k เราจะย้อนรอย
ทีนี้ก็เกิดคำถามขึ้นมาว่า เราจะแน่ใจได้อย่างไรว่าเส้นทางนั้นเรียบง่ายและไม่วนลูปเป็นวงจร? ในที่นี้ แนวคิดคือการติดตามจุดยอดเส้นทางปัจจุบันในอาร์เรย์ ในกรณีนี้ เมื่อใดก็ตามที่เราเพิ่มจุดยอดให้กับเส้นทาง เราจะตรวจสอบว่าจุดยอดมีอยู่แล้วหรือไม่อยู่ในเส้นทางปัจจุบัน เห็นว่าถ้ามีเราละเลยขอบ
ตัวอย่าง
// Program to find if there is a simple path with
// weight more than k
#include<bits/stdc++.h>
using namespace std;
// iPair ==> Integer Pair
typedef pair<int, int> iPair;
// Now this class represents a dipathted graph using
// adjacency list representation
class Graph{
int V1; // Indicates no. of vertices
// In this case, in a weighted graph, we need to store vertex
// and weight pair for every edge
list< pair<int, int>> *adj1;
bool pathMoreThanKUtil(int src1, int k, vector<bool>&path1);
public:
Graph(int V1); // Shows constructor
// Shows function to add an edge to graph
void addEdge(int u1, int v1, int w1);
bool pathMoreThanK(int src1, int k);
};
// Used to return true if graph has path more than k length
bool Graph::pathMoreThanK(int src1, int k){
// Used to create a path array with nothing included
// in path
vector<bool> path1(V1, false);
// Used to add source vertex to path
path1[src1] = 1;
return pathMoreThanKUtil(src1, k, path1);
}
// Used to print shortest paths from src to all other vertices
bool Graph::pathMoreThanKUtil(int src1, int k, vector<bool>&path1){
// Now if k is 0 or negative, return true;
if (k <= 0)
return true;
//Used to get all adjacent vertices of source vertex src and
// recursively explore all paths from src.
list<iPair>::iterator i;
for (i = adj1[src1].begin(); i != adj1[src1].end(); ++i){
// Used to get adjacent vertex and weight of edge
int v1 = (*i).first;
int w1 = (*i).second;
// Now if vertex v is already there in path, then
// there is a cycle (we ignore this edge)
if (path1[v1] == true)
continue;
// Now if weight of is more than k, return true
if (w1 >= k)
return true;
// Else add this vertex to path
path1[v1] = true;
// Now if this adjacent can provide a path longer
// than k, return true.
if (pathMoreThanKUtil(v1, k-w1, path1))
return true;
// Backtrack
path1[v1] = false;
}
// Now if no adjacent could produce longer path, return
// false
return false;
}
// Used to allocates memory for adjacency list
Graph::Graph(int V1){
this->V1 = V1;
adj1 = new list<iPair> [V1];
}
//Shows utility function to an edge (u, v) of weight w
void Graph::addEdge(int u1, int v1, int w1){
adj1[u1].push_back(make_pair(v1, w1));
adj1[v1].push_back(make_pair(u1, w1));
}
// Driver program to test methods of graph class
int main(){
// Used to create the graph given in above fugure
int V1 = 9;
Graph g(V1);
// making above shown graph
g.addEdge(0, 1, 5);
g.addEdge(0, 7, 9);
g.addEdge(1, 2, 9);
g.addEdge(1, 7, 12);
g.addEdge(2, 3, 8);
g.addEdge(2, 8, 3);
g.addEdge(2, 5, 10);
g.addEdge(3, 4, 10);
g.addEdge(3, 5, 15);
g.addEdge(4, 5, 11);
g.addEdge(5, 6, 3);
g.addEdge(6, 7, 2);
g.addEdge(6, 8, 7);
g.addEdge(7, 8, 8);
int src1 = 0;
int k = 70;
g.pathMoreThanK(src1, k)? cout << "Yes\n" :
cout << "No\n";
k = 68;
g.pathMoreThanK(src1, k)? cout << "Yes\n" :
cout << "No\n";
return 0;
} ผลลัพธ์
No Yes