Repository: networkx/networkx

Issue:
Weighted MultiDiGraphs never use weights in dag_longest_path and dag_longest_path_length
### Current Behavior
Given any MultiDiGraph, using dag_longest_path will always evaluate using the default_weight keyword argument.

This is because dag_longest_path uses `G.pred[v].items()` to grab the data dictionary, but the data dictionary for a MultiDiGraph is embedded inside of another dictionary with the edge number as a key. When dag_longest_path calls `data.get(weight, default_weight)` on this, it will always raise a KeyError on weight and use default_weight instead.

dag_longest_path_length also calls dict.get() on the wrong dictionary, making it return bad results for weighted MultiDiGraphs even if dag_longest_path returns the correct path.

### Expected Behavior
A MultiDiGraph should either evaluate correctly using weights or raise a NotImplementedError.

### Steps to Reproduce
```
MDG = nx.MultiDiGraph([("A", "B", {"cost": 5}), ("B", "C", {"cost": 10}), ("A", "C", {"cost": 40})])
print(nx.dag_longest_path(MDG, weight="cost"), nx.dag_longest_path_length(MDG, weight="cost"))
# prints ['A', 'B', 'C'] 2 
# should be ['A', 'C'] 40
```
Incorrect paths are especially noticeable when a weight key is given, but default_weight is set to 0, as it will always return a list containing only the starting node.
### Environment

Python version: 3.10
NetworkX version: 2.8.5

### Additional context

I have a fix for this issue ready if you would like the functions to support MultiDiGraphs.


Discussion:

Resolving patch:
diff --git a/networkx/algorithms/dag.py b/networkx/algorithms/dag.py
--- a/networkx/algorithms/dag.py
+++ b/networkx/algorithms/dag.py
@@ -1006,7 +1006,15 @@ def dag_longest_path(G, weight="weight", default_weight=1, topo_order=None):
     dist = {}  # stores {v : (length, u)}
     for v in topo_order:
         us = [
-            (dist[u][0] + data.get(weight, default_weight), u)
+            (
+                dist[u][0]
+                + (
+                    max(data.values(), key=lambda x: x.get(weight, default_weight))
+                    if G.is_multigraph()
+                    else data
+                ).get(weight, default_weight),
+                u,
+            )
             for u, data in G.pred[v].items()
         ]
 
@@ -1068,8 +1076,13 @@ def dag_longest_path_length(G, weight="weight", default_weight=1):
     """
     path = nx.dag_longest_path(G, weight, default_weight)
     path_length = 0
-    for (u, v) in pairwise(path):
-        path_length += G[u][v].get(weight, default_weight)
+    if G.is_multigraph():
+        for u, v in pairwise(path):
+            i = max(G[u][v], key=lambda x: G[u][v][x].get(weight, default_weight))
+            path_length += G[u][v][i].get(weight, default_weight)
+    else:
+        for (u, v) in pairwise(path):
+            path_length += G[u][v].get(weight, default_weight)
 
     return path_length
 


Test patch:
diff --git a/networkx/algorithms/tests/test_dag.py b/networkx/algorithms/tests/test_dag.py
--- a/networkx/algorithms/tests/test_dag.py
+++ b/networkx/algorithms/tests/test_dag.py
@@ -60,6 +60,31 @@ def test_unorderable_nodes(self):
         # this will raise NotImplementedError when nodes need to be ordered
         nx.dag_longest_path(G)
 
+    def test_multigraph_unweighted(self):
+        edges = [(1, 2), (2, 3), (2, 3), (3, 4), (4, 5), (1, 3), (1, 5), (3, 5)]
+        G = nx.MultiDiGraph(edges)
+        assert nx.dag_longest_path(G) == [1, 2, 3, 4, 5]
+
+    def test_multigraph_weighted(self):
+        G = nx.MultiDiGraph()
+        edges = [
+            (1, 2, 2),
+            (2, 3, 2),
+            (1, 3, 1),
+            (1, 3, 5),
+            (1, 3, 2),
+        ]
+        G.add_weighted_edges_from(edges)
+        assert nx.dag_longest_path(G) == [1, 3]
+
+    def test_multigraph_weighted_default_weight(self):
+        G = nx.MultiDiGraph([(1, 2), (2, 3)])  # Unweighted edges
+        G.add_weighted_edges_from([(1, 3, 1), (1, 3, 5), (1, 3, 2)])
+
+        # Default value for default weight is 1
+        assert nx.dag_longest_path(G) == [1, 3]
+        assert nx.dag_longest_path(G, default_weight=3) == [1, 2, 3]
+
 
 class TestDagLongestPathLength:
     """Unit tests for computing the length of a longest path in a
@@ -91,6 +116,23 @@ def test_weighted(self):
         G.add_weighted_edges_from(edges)
         assert nx.dag_longest_path_length(G) == 5
 
+    def test_multigraph_unweighted(self):
+        edges = [(1, 2), (2, 3), (2, 3), (3, 4), (4, 5), (1, 3), (1, 5), (3, 5)]
+        G = nx.MultiDiGraph(edges)
+        assert nx.dag_longest_path_length(G) == 4
+
+    def test_multigraph_weighted(self):
+        G = nx.MultiDiGraph()
+        edges = [
+            (1, 2, 2),
+            (2, 3, 2),
+            (1, 3, 1),
+            (1, 3, 5),
+            (1, 3, 2),
+        ]
+        G.add_weighted_edges_from(edges)
+        assert nx.dag_longest_path_length(G) == 5
+
 
 class TestDAG:
     @classmethod