using System;
using System.Collections.Generic;
class Program
{
class PriorityQueue<T>
{
private SortedSet<T> set;
public PriorityQueue(IComparer<T> comparer)
{
set = new SortedSet<T>(comparer);
}
public int Count => set.Count;
public void Enqueue(T item)
{
set.Add(item);
}
public T Dequeue()
{
T item = set.Min;
set.Remove(item);
return item;
}
}
static List<int> Dijkstra(int u, int b, int n, List<Tuple<int, int>>[] adj)
{
List<int> dis = new List<int>();
dis.AddRange(new int[n + 1]);
for (int i = 0; i <= n; i++)
{
dis[i] = 1000000001;
}
var pq = new PriorityQueue<Tuple<int, int>>(Comparer<Tuple<int, int>>.Create((x, y) => x.Item1.CompareTo(y.Item1)));
dis[u] = 0;
pq.Enqueue(new Tuple<int, int>(0, u));
while (pq.Count > 0)
{
Tuple<int, int> top = pq.Dequeue();
int uu = top.Item2;
foreach (var p in adj[uu])
{
int v = p.Item1;
int w = p.Item2;
if (dis[v] > dis[uu] + w)
{
dis[v] = dis[uu] + w;
pq.Enqueue(new Tuple<int, int>(dis[v], v));
}
}
}
return dis;
}
static int ShortestPath(int n, int m, int a, int b, List<List<int>> edges)
{
List<Tuple<int, int>>[] adj = new List<Tuple<int, int>>[n + 1];
for (int i = 0; i <= n; i++)
{
adj[i] = new List<Tuple<int, int>>();
}
List<List<int>> curved = new List<List<int>>();
for (int i = 0; i < m; i++)
{
int u = edges[i][0];
int v = edges[i][1];
int w = edges[i][2];
int cw = edges[i][3];
adj[u].Add(new Tuple<int, int>(v, w));
adj[v].Add(new Tuple<int, int>(u, w));
// curved edge weight
curved.Add(new List<int> { u, v, cw });
}
List<int> da = Dijkstra(a, b, n, adj);
List<int> db = Dijkstra(b, a, n, adj);
int ans = da[b];
// ans = min distance from a -> b with at max one
// curved edge current ans without curved edge from
// a -> b = da[b]
for (int i = 0; i < m; i++)
{
int u = curved[i][0];
int v = curved[i][1];
int cw = curved[i][2];
ans = Math.Min(ans, da[u] + cw + db[v]);
ans = Math.Min(ans, da[v] + cw + db[u]);
}
if (ans >= 1000000001)
return -1;
return ans;
}
// Driver code
static void Main()
{
// Number of nodes
int n = 54;
// Number of edges
int m = 4;
// Source node
int a = 2;
// Destination node
int b = 4;
// Edges in the format {u, v, weight,
// curved_edge_weight}
List<List<int>> edges = new List<List<int>> {
new List<int> { 1, 2, 1, 4 },
new List<int> { 1, 3, 2, 4 },
new List<int> { 1, 4, 3, 1 },
new List<int> { 2, 4, 6, 5 }
};
int result = ShortestPath(n, m, a, b, edges);
Console.Write("Minimum distance from node " + a +
" to node " + b + " is: ");
if (result == -1)
{
Console.Write("No path exists.");
}
else
{
Console.Write(result);
}
}
}