// C# program for the above approach
using System;
using System.Collections.Generic;
class Program
{
const int INF = 1000000000;
// Function for Dijkstra Algorithm to
// find single source shortest path
static void Dijkstra(int source, int n, List<(int, int)>[] adj, int[] dist)
{
// Resize dist[] to N and assign
// any large value to it
Array.Fill(dist, INF);
// Initialise distance of source
// node as 0
dist[source] = 0;
// Using min-heap priority_queue
// for sorting wrt edges_cost
var pq = new SortedSet<(int, int)>(Comparer<(int, int)>.Create((a, b) => a.Item1.CompareTo(b.Item1)));
// Push the current dist[source]
// and source to pq
pq.Add((dist[source], source));
// Until priority queue is empty
while (pq.Count > 0)
{
// Store the cost of linked
// node to edges
var u = pq.Min;
// int d = pq.top().first;
// Pop the top node
pq.Remove(u);
// Iterate over edges
foreach (var edge in adj[u.Item2])
{
// Find the starting and
// ending vertex of edge
int v = edge.Item1, w = edge.Item2;
// Update the distance of
// node v to minimum of
// dist[u] + w if it is
// minimum
if (dist[u.Item2] + w < dist[v])
{
pq.Remove((dist[v], v));
dist[v] = dist[u.Item2] + w;
pq.Add((dist[v], v));
}
}
}
}
// Function to find the minimum cost
// between node 1 to node n
static void MinCostPath(List<(int, (int, int))> edges, int n, int M)
{
// To create Adjacency List
var adj = new List<(int, int)>[100005];
for (int i = 0; i < adj.Length; i++) adj[i] = new List<(int, int)>();
// Iterate over edges
foreach (var edge in edges)
{
// Get source, destination and
// edges of edges[i]
int x = edge.Item1, y = edge.Item2.Item1, z = edge.Item2.Item2;
// Create Adjacency List
adj[x].Add((y, z));
adj[y].Add((x, z));
}
// To store the cost from node 1
// and node N
var distFromSource = new int[n + 1];
var distFromDest = new int[n + 1];
// Find the cost of travel between
// source(1) to any vertex
Dijkstra(1, n + 1, adj, distFromSource);
// Find the cost of travel between
// destination(n) to any vertex
Dijkstra(n, n + 1, adj, distFromDest);
// Initialise the minimum cost
int minCost = distFromSource[n];
// Traverse the edges
foreach (var it in edges)
{
// Get the edges
int u = it.Item1, v = it.Item2.Item1, c = it.Item2.Item2;
// Find the current cost from
// node 1 to u and node u to v
// and node v to N with only
// current edge cost reduced
// to half
int curCost = distFromSource[u] + c / 2 + distFromDest[v];
// Update the min_cost
minCost = Math.Min(minCost, curCost);
}
// Print the minimum cost
Console.WriteLine(minCost);
}
// Driver Code
static void Main()
{
// Give Nodes and Edges
int N = 3;
int M = 3;
// Given Edges with cost
var edges = new List<(int, (int, int))>
{
(2, (3, 1)),
(1, (3, 7)),
(2, (1, 5))
};
MinCostPath(edges, N, M);
}
}