You are given a Directed Acyclic Graph (DAG) with n nodes labeled from 0 to n - 1, represented by a 2D array edges, where edges[i] = [u_i, v_i] indicates a directed edge from node u_i to v_i.
Each node has an associated score given in an array score, where score[i] represents the score of node i.
You must process the nodes in a valid topological order. Each node is assigned a 1-based position in the processing order. The profit is calculated by summing up the product of each node's score and its position in the ordering.
Return the maximum possible profit achievable with an optimal topological order.
A topological order of a DAG is a linear ordering of its nodes such that for every directed edge u → v, node u comes before v in the ordering.
💡 Note:Edge 0→2 constrains the ordering. Valid orders are [0,1,2], [1,0,2], and [0,2,1]. Calculating profits: [0,1,2] gives 1×1 + 3×2 + 2×3 = 13, [1,0,2] gives 3×1 + 1×2 + 2×3 = 11, and [0,2,1] gives 1×1 + 2×2 + 3×3 = 14. The optimal order [0,2,1] maximizes profit at 14.
Example 3 — No Edges
$Input:edges = [], score = [2,1,3]
›Output:14
💡 Note:No edges means no constraints. To maximize profit, place nodes with higher scores in later positions. Optimal order [1,0,2] gives 1×1 + 2×2 + 3×3 = 1 + 4 + 9 = 14
Maximum Profit from Valid Topological Order in DAG — Solution
The key insight is to use a greedy approach with topological sorting: when multiple nodes have in-degree 0, always choose the one with the highest score to place later in the ordering (higher position = higher multiplier). This can be efficiently implemented using Kahn's algorithm with a max-heap priority queue. Best approach is greedy topological sort with Time: O(V + E + V log V), Space: O(V + E).
Common Approaches
✓
Brute Force - All Topological Orders
⏱️ Time: O(n! × n)
Space: O(n)
Use DFS with backtracking to generate every possible valid topological ordering. For each ordering, calculate the total profit by multiplying each node's score with its 1-based position. Keep track of the maximum profit found.
Greedy Approach with Topological Sort
⏱️ Time: O(V + E + V log V)
Space: O(V + E)
Perform topological sort using Kahn's algorithm, but when multiple nodes have in-degree 0, prioritize nodes with higher scores to assign them later positions (higher multipliers).
Brute Force - All Topological Orders — Algorithm Steps
Build adjacency list and in-degree array
Use DFS backtracking to generate all valid topological orders
For each order, calculate profit = Σ(score[node] × position)
Return maximum profit found
Visualization
Tap to expand
Step-by-Step Walkthrough
1
Build Graph
Create adjacency list and calculate in-degrees
2
Generate Orders
Use backtracking to try all valid topological orderings
3
Calculate Profit
For each order, multiply score[i] × position and sum up
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
long long maxProfit = 0;
void backtrack(int* currentOrder, int orderSize, bool* remaining, int** adj, int* adjSizes,
int* score, int* tempInDegree, int n) {
bool hasRemaining = false;
for (int i = 0; i < n; i++) {
if (remaining[i]) {
hasRemaining = true;
break;
}
}
if (!hasRemaining) {
long long profit = 0;
for (int i = 0; i < orderSize; i++) {
profit += (long long)score[currentOrder[i]] * (i + 1);
}
if (profit > maxProfit) maxProfit = profit;
return;
}
for (int node = 0; node < n; node++) {
if (remaining[node] && tempInDegree[node] == 0) {
currentOrder[orderSize] = node;
remaining[node] = false;
int* newInDegree = malloc(n * sizeof(int));
memcpy(newInDegree, tempInDegree, n * sizeof(int));
for (int i = 0; i < adjSizes[node]; i++) {
newInDegree[adj[node][i]]--;
}
backtrack(currentOrder, orderSize + 1, remaining, adj, adjSizes, score, newInDegree, n);
free(newInDegree);
remaining[node] = true;
}
}
}
int solution(int** edges, int edgesSize, int* score, int n) {
if (n == 0) return 0;
int** adj = malloc(n * sizeof(int*));
int* adjSizes = calloc(n, sizeof(int));
int* inDegree = calloc(n, sizeof(int));
// Count adjacencies first
for (int i = 0; i < edgesSize; i++) {
adjSizes[edges[i][0]]++;
inDegree[edges[i][1]]++;
}
// Allocate adjacency lists
for (int i = 0; i < n; i++) {
adj[i] = malloc(adjSizes[i] * sizeof(int));
adjSizes[i] = 0; // Reset for filling
}
// Fill adjacency lists
for (int i = 0; i < edgesSize; i++) {
adj[edges[i][0]][adjSizes[edges[i][0]]++] = edges[i][1];
}
maxProfit = 0;
int* currentOrder = malloc(n * sizeof(int));
bool* remaining = malloc(n * sizeof(bool));
for (int i = 0; i < n; i++) remaining[i] = true;
backtrack(currentOrder, 0, remaining, adj, adjSizes, score, inDegree, n);
// Cleanup
for (int i = 0; i < n; i++) free(adj[i]);
free(adj);
free(adjSizes);
free(inDegree);
free(currentOrder);
free(remaining);
return (int)maxProfit;
}
int parseEdges(char* str, int*** edges) {
if (strlen(str) <= 2) {
*edges = NULL;
return 0;
}
int count = 0;
for (int i = 0; str[i]; i++) {
if (str[i] == '[' && i > 0) count++;
}
if (count == 0) {
*edges = NULL;
return 0;
}
*edges = malloc(count * sizeof(int*));
for (int i = 0; i < count; i++) {
(*edges)[i] = malloc(2 * sizeof(int));
}
int idx = 0;
char* ptr = str + 1;
while (*ptr && idx < count) {
if (*ptr == '[') {
ptr++;
(*edges)[idx][0] = strtol(ptr, &ptr, 10);
if (*ptr == ',') ptr++;
(*edges)[idx][1] = strtol(ptr, &ptr, 10);
idx++;
}
ptr++;
}
return idx;
}
int parseScore(char* str, int** score) {
if (strlen(str) <= 2) {
*score = NULL;
return 0;
}
int count = 1;
for (int i = 0; str[i]; i++) {
if (str[i] == ',') count++;
}
*score = malloc(count * sizeof(int));
int idx = 0;
char* ptr = str + 1;
while (*ptr && idx < count) {
(*score)[idx++] = strtol(ptr, &ptr, 10);
if (*ptr == ',') ptr++;
}
return idx;
}
int main() {
char edgesStr[10000], scoreStr[10000];
fgets(edgesStr, sizeof(edgesStr), stdin);
fgets(scoreStr, sizeof(scoreStr), stdin);
// Remove newlines
edgesStr[strcspn(edgesStr, "\n")] = 0;
scoreStr[strcspn(scoreStr, "\n")] = 0;
int** edges;
int* score;
int edgesSize = parseEdges(edgesStr, &edges);
int n = parseScore(scoreStr, &score);
printf("%d\n", solution(edges, edgesSize, score, n));
if (edges) {
for (int i = 0; i < edgesSize; i++) free(edges[i]);
free(edges);
}
if (score) free(score);
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
O(n! × n)
Up to n! possible topological orders, each taking O(n) time to calculate profit
n
2n
⚡ Linearithmic
Space Complexity
O(n)
Recursion stack depth and temporary arrays for tracking current order
n
2n
✓ Linear Space
12.5K Views
MediumFrequency
~35 minAvg. Time
234 Likes
Ln 1, Col 1
Smart Actions
💡Explanation
AI Ready
💡 SuggestionTabto acceptEscto dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen
Algorithm Visualization
Pinch to zoom • Tap outside to close
Test Cases
0 passed
0 failed
3 pending
Select Compiler
Choose a programming language
Compiler list would appear here...
AI Editor Features
Header Buttons
💡
Explain
Get a detailed explanation of your code. Select specific code or analyze the entire file. Understand algorithms, logic flow, and complexity.
🔧
Fix
Automatically detect and fix issues in your code. Finds bugs, syntax errors, and common mistakes. Shows you what was fixed.
💡
Suggest
Get improvement suggestions for your code. Best practices, performance tips, and code quality recommendations.
💬
Ask AI
Open an AI chat assistant to ask any coding questions. Have a conversation about your code, get help with debugging, or learn new concepts.
Smart Actions (Slash Commands)
🔧
/fix Enter
Find and fix issues in your code. Detects common problems and applies automatic fixes.
💡
/explain Enter
Get a detailed explanation of what your code does, including time/space complexity analysis.
🧪
/tests Enter
Automatically generate unit tests for your code. Creates comprehensive test cases.
📝
/docs Enter
Generate documentation for your code. Creates docstrings, JSDoc comments, and type hints.
⚡
/optimize Enter
Get performance optimization suggestions. Improve speed and reduce memory usage.
AI Code Completion (Copilot-style)
👻
Ghost Text Suggestions
As you type, AI suggests code completions shown in gray text. Works with keywords like def, for, if, etc.
Tabto acceptEscto dismiss
💬
Comment-to-Code
Write a comment describing what you want, and AI generates the code. Try: # two sum, # binary search, # fibonacci
💡
Pro Tip: Select specific code before using Explain, Fix, or Smart Actions to analyze only that portion. Otherwise, the entire file will be analyzed.