//C# code for the above approach
using System;
using System.Collections.Generic;
using System.Linq;
class GFG
{
// Adjacency list to store the edges.
List<List<Tuple<int, int>>> adj = new List<List<Tuple<int, int>>>();
// To store maximum points of a path
// starting at a node
List<int> dp = new List<int>();
// Visited vector to keep track of nodes for
// which dp values have already been calculated
List<bool> vis = new List<bool>();
// To store the final answer
int ans = 0;
// Function for visiting every node and
// calculating dp values for each node.
void dfs(int currNode, List<int> points)
{
// Mark the current node as visited so
// that it does not have to be visited again.
vis[currNode] = true;
// To store maximum path starting
// at node minus length of edge connecting
// that node to the current node for each
// child of the current node.
List<int> childNodes = new List<int>();
// Iterating through each child
// of the current node.
foreach (var edge in adj[currNode])
{
int childNode = edge.Item1;
int edgeLength = edge.Item2;
// To check whether the child has been
// already visited or not
if (!vis[childNode])
{
// Call dfs function for the child
dfs(childNode, points);
}
// Push the value (maximum points path
// starting at this child node minus length
// of edge) into the list
childNodes.Add(dp[childNode] - edgeLength);
}
// Sort the list in decreasing order
// to pick the maximum 2 values.
childNodes.Sort((a, b) => b.CompareTo(a));
// max1 - to store maximum points path
// starting at a child node of the current
// node, max2 - to store the second maximum
// points path starting at a child node
// of the current node.
int max1 = 0, max2 = 0;
if (childNodes.Count >= 2)
{
max1 = Math.Max(max1, childNodes[0]);
max2 = Math.Max(max2, childNodes[1]);
}
else if (childNodes.Count >= 1)
{
max1 = Math.Max(max1, childNodes[0]);
}
// Calculate maximum points path passing
// through the current node.
ans = Math.Max(ans, max1 + max2 + points[currNode]);
// Store the maximum points path starting
// at the current node in dp[currNode]
dp[currNode] = max1 + points[currNode];
}
// To find the maximal points path
int MaxPointPath(int n, List<int> points, List<List<int>> edges)
{
adj = new List<List<Tuple<int, int>>>(n + 1);
dp = new List<int>(n + 1);
vis = new List<bool>(n + 1);
for (int i = 0; i <= n; i++)
{
adj.Add(new List<Tuple<int, int>>());
dp.Add(0);
vis.Add(false);
}
// Filling adjacency list
foreach (var edge in edges)
{
int u = edge[0];
int v = edge[1];
int w = edge[2];
adj[u].Add(new Tuple<int, int>(v, w));
adj[v].Add(new Tuple<int, int>(u, w));
}
// Calling dfs for node 1
dfs(1, points);
return ans;
}
static void Main()
{
GFG obj = new GFG();
// Number of Vertices
int n = 5;
// Points at each node
List<int> points = new List<int>(n + 1)
{
0, 6, 3, 2, 5, 0
};
// Edges and their lengths
List<List<int>> edges = new List<List<int>>
{
new List<int> { 1, 2, 10 },
new List<int> { 2, 3, 3 },
new List<int> { 2, 4, 1 },
new List<int> { 1, 5, 11 }
};
Console.WriteLine(obj.MaxPointPath(n, points, edges));
}
}