Karp's minimum mean (or average) weight cycle algorithm
Last Updated : 21 May, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report
Given a directed and strongly connected graph with non-negative edge weights. We define the mean weight of a cycle as the summation of all the edge weights of the cycle divided by the no. of edges. Our task is to find the minimum mean weight among all the directed cycles of the graph.
The input is provided as a list of edges, where each edge is represented by a triplet [u, v, w] indicating a directed edge from node u to node v with weight w. Nodes are labeled from 0 to n-1, and the graph is guaranteed to be strongly connected, meaning a path exists between every pair of nodes.
Method to find the smallest mean weight value cycle efficiently
Step 1: Choose first vertex as source.
Step 2: Compute the shortest path to all other vertices on a path consisting of k edges 0 <= k <= V where V is number of vertices. This is a simple dp problem which can be computed by the recursive solution dp[k][v] = min(dp[k][v], dp[k-1][u] + weight(u,v) where v is the destination and the edge(u,v) should belong to E
Step 3: For each vertex calculate max(dp[n][v]-dp[k][v])/(n-k) where 0<=k<=n-1
Step 4: The minimum of the values calculated above is the required answer.
Implementation:
C++
// C++ program to find minimum average// weight of a cycle in connected and// directed graph.#include<bits/stdc++.h>usingnamespacestd;constintV=4;// a struct to represent edgesstructedge{intfrom,weight;};// vector to store edgesvector<edge>edges[V];voidaddedge(intu,intv,intw){edges[v].push_back({u,w});}// calculates the shortest pathvoidshortestpath(intdp[][V]){// initializing all distances as -1for(inti=0;i<=V;i++)for(intj=0;j<V;j++)dp[i][j]=-1;// shortest distance from first vertex// to in itself consisting of 0 edgesdp[0][0]=0;// filling up the dp tablefor(inti=1;i<=V;i++){for(intj=0;j<V;j++){for(intk=0;k<edges[j].size();k++){if(dp[i-1][edges[j][k].from]!=-1){intcurr_wt=dp[i-1][edges[j][k].from]+edges[j][k].weight;if(dp[i][j]==-1)dp[i][j]=curr_wt;elsedp[i][j]=min(dp[i][j],curr_wt);}}}}}// Returns minimum value of average weight of a// cycle in graph.doubleminAvgWeight(){intdp[V+1][V];shortestpath(dp);// array to store the avg valuesdoubleavg[V];for(inti=0;i<V;i++)avg[i]=-1;// Compute average values for all vertices using// weights of shortest paths store in dp.for(inti=0;i<V;i++){if(dp[V][i]!=-1){for(intj=0;j<V;j++)if(dp[j][i]!=-1)avg[i]=max(avg[i],((double)dp[V][i]-dp[j][i])/(V-j));}}// Find minimum value in avg[]doubleresult=avg[0];for(inti=0;i<V;i++)if(avg[i]!=-1&&avg[i]<result)result=avg[i];returnresult;}// Driver functionintmain(){addedge(0,1,1);addedge(0,2,10);addedge(1,2,3);addedge(2,3,2);addedge(3,1,0);addedge(3,0,8);cout<<minAvgWeight();return0;}
Java
// Java program to find minimum average // weight of a cycle in connected and // directed graph.importjava.io.*;importjava.util.*;classGFG{staticintV=4;// a struct to represent edgesstaticclassEdge{intfrom,weight;Edge(intfrom,intweight){this.from=from;this.weight=weight;}}// vector to store edges//@SuppressWarnings("unchecked")staticVector<Edge>[]edges=newVector[V];static{for(inti=0;i<V;i++)edges[i]=newVector<>();}staticvoidaddedge(intu,intv,intw){edges[v].add(newEdge(u,w));}// calculates the shortest pathstaticvoidshortestpath(int[][]dp){// initializing all distances as -1for(inti=0;i<=V;i++)for(intj=0;j<V;j++)dp[i][j]=-1;// shortest distance from first vertex// to in itself consisting of 0 edgesdp[0][0]=0;// filling up the dp tablefor(inti=1;i<=V;i++){for(intj=0;j<V;j++){for(intk=0;k<edges[j].size();k++){if(dp[i-1][edges[j].elementAt(k).from]!=-1){intcurr_wt=dp[i-1][edges[j].elementAt(k).from]+edges[j].elementAt(k).weight;if(dp[i][j]==-1)dp[i][j]=curr_wt;elsedp[i][j]=Math.min(dp[i][j],curr_wt);}}}}}// Returns minimum value of average weight // of a cycle in graph.staticdoubleminAvgWeight(){int[][]dp=newint[V+1][V];shortestpath(dp);// array to store the avg valuesdouble[]avg=newdouble[V];for(inti=0;i<V;i++)avg[i]=-1;// Compute average values for all vertices using// weights of shortest paths store in dp.for(inti=0;i<V;i++){if(dp[V][i]!=-1){for(intj=0;j<V;j++)if(dp[j][i]!=-1)avg[i]=Math.max(avg[i],((double)dp[V][i]-dp[j][i])/(V-j));}}// Find minimum value in avg[]doubleresult=avg[0];for(inti=0;i<V;i++)if(avg[i]!=-1&&avg[i]<result)result=avg[i];returnresult;}// Driver Codepublicstaticvoidmain(String[]args){addedge(0,1,1);addedge(0,2,10);addedge(1,2,3);addedge(2,3,2);addedge(3,1,0);addedge(3,0,8);System.out.printf("%.5f",minAvgWeight());}}// This code is contributed by// sanjeev2552
Python3
# Python3 program to find minimum # average weight of a cycle in # connected and directed graph. # a struct to represent edges classedge:def__init__(self,u,w):self.From=uself.weight=wdefaddedge(u,v,w):edges[v].append(edge(u,w))# calculates the shortest path defshortestpath(dp):# initializing all distances as -1foriinrange(V+1):forjinrange(V):dp[i][j]=-1# shortest distance From first vertex # to in itself consisting of 0 edges dp[0][0]=0# filling up the dp tableforiinrange(1,V+1):forjinrange(V):forkinrange(len(edges[j])):if(dp[i-1][edges[j][k].From]!=-1):curr_wt=(dp[i-1][edges[j][k].From]+edges[j][k].weight)if(dp[i][j]==-1):dp[i][j]=curr_wtelse:dp[i][j]=min(dp[i][j],curr_wt)# Returns minimum value of average # weight of a cycle in graph. defminAvgWeight():dp=[[None]*Vforiinrange(V+1)]shortestpath(dp)# array to store the avg values avg=[-1]*V# Compute average values for all # vertices using weights of # shortest paths store in dp.foriinrange(V):if(dp[V][i]!=-1):forjinrange(V):if(dp[j][i]!=-1):avg[i]=max(avg[i],(dp[V][i]-dp[j][i])/(V-j))# Find minimum value in avg[] result=avg[0]foriinrange(V):if(avg[i]!=-1andavg[i]<result):result=avg[i]returnresult# Driver CodeV=4# vector to store edges edges=[[]foriinrange(V)]addedge(0,1,1)addedge(0,2,10)addedge(1,2,3)addedge(2,3,2)addedge(3,1,0)addedge(3,0,8)print(minAvgWeight())# This code is contributed by Pranchalk
C#
// C# program to find minimum // average weight of a cycle // in connected and directed graph. usingSystem;usingSystem.Collections.Generic;classGFG{staticintV=4;// a struct to represent// edges publicclassEdge{publicintfrom,weight;publicEdge(intfrom,intweight){this.from=from;this.weight=weight;}}// vector to store edges staticList<Edge>[]edges=newList<Edge>[V];staticvoidaddedge(intu,intv,intw){edges[v].Add(newEdge(u,w));}// calculates the shortest path staticvoidshortestpath(int[,]dp){// initializing all distances // as -1 for(inti=0;i<=V;i++)for(intj=0;j<V;j++)dp[i,j]=-1;// shortest distance from // first vertex to in itself // consisting of 0 edges dp[0,0]=0;// filling up the dp table for(inti=1;i<=V;i++){for(intj=0;j<V;j++){for(intk=0;k<edges[j].Count;k++){if(dp[i-1,edges[j][k].from]!=-1){intcurr_wt=dp[i-1,edges[j][k].from]+edges[j][k].weight;if(dp[i,j]==-1)dp[i,j]=curr_wt;elsedp[i,j]=Math.Min(dp[i,j],curr_wt);}}}}}// Returns minimum value of // average weight of a cycle // in graph. staticdoubleminAvgWeight(){int[,]dp=newint[V+1,V];shortestpath(dp);// array to store the // avg values double[]avg=newdouble[V];for(inti=0;i<V;i++)avg[i]=-1;// Compute average values for // all vertices using weights // of shortest paths store in dp. for(inti=0;i<V;i++){if(dp[V,i]!=-1){for(intj=0;j<V;j++)if(dp[j,i]!=-1)avg[i]=Math.Max(avg[i],((double)dp[V,i]-dp[j,i])/(V-j));}}// Find minimum value in avg[] doubleresult=avg[0];for(inti=0;i<V;i++)if(avg[i]!=-1&&avg[i]<result)result=avg[i];returnresult;}// Driver Code publicstaticvoidMain(String[]args){for(inti=0;i<V;i++)edges[i]=newList<Edge>();addedge(0,1,1);addedge(0,2,10);addedge(1,2,3);addedge(2,3,2);addedge(3,1,0);addedge(3,0,8);Console.Write("{0:F5}",minAvgWeight());}}// This code is contributed by Princi Singh
JavaScript
<script>// JavaScript program to find minimum // average weight of a cycle // in connected and directed graph. varV=4;// a struct to represent// edges classEdge{constructor(from,weight){this.from=from;this.weight=weight;}}// vector to store edges varedges=Array.from(Array(V),()=>Array());functionaddedge(u,v,w){edges[v].push(newEdge(u,w));}// calculates the shortest path functionshortestpath(dp){// initializing all distances // as -1 for(vari=0;i<=V;i++)for(varj=0;j<V;j++)dp[i][j]=-1;// shortest distance from // first vertex to in itself // consisting of 0 edges dp[0][0]=0;// filling up the dp table for(vari=1;i<=V;i++){for(varj=0;j<V;j++){for(vark=0;k<edges[j].length;k++){if(dp[i-1][edges[j][k].from]!=-1){varcurr_wt=dp[i-1][edges[j][k].from]+edges[j][k].weight;if(dp[i][j]==-1)dp[i][j]=curr_wt;elsedp[i][j]=Math.min(dp[i][j],curr_wt);}}}}}// Returns minimum value of // average weight of a cycle // in graph. functionminAvgWeight(){vardp=Array.from(Array(V+1),()=>Array(V).fill(0))shortestpath(dp);// array to store the // avg values varavg=Array(V).fill(0);for(vari=0;i<V;i++)avg[i]=-1;// Compute average values for // all vertices using weights // of shortest paths store in dp. for(vari=0;i<V;i++){if(dp[V][i]!=-1){for(varj=0;j<V;j++)if(dp[j][i]!=-1)avg[i]=Math.max(avg[i],(dp[V][i]-dp[j][i])/(V-j));}}// Find minimum value in avg[] varresult=avg[0];for(vari=0;i<V;i++)if(avg[i]!=-1&&avg[i]<result)result=avg[i];returnresult;}// Driver Code addedge(0,1,1);addedge(0,2,10);addedge(1,2,3);addedge(2,3,2);addedge(3,1,0);addedge(3,0,8);document.write(minAvgWeight().toFixed(5));</script>
Output
1.66667
Time Complexity : The time complexity of the given program is O(V^3), where V is the number of vertices in the graph. This is because the program uses a nested loop to fill up the dp table, and the size of the dp table is V^2. The outermost loop runs V times, the middle loop runs V times, and the innermost loop can run up to V times in the worst case, giving a total time complexity of O(V^3). The other parts of the program have a lower time complexity and do not contribute significantly to the overall time complexity.
Space Complexity : The space complexity of the given program is O(V^2), where V is the number of vertices in the graph. This is because the program creates a 2D array dp of size (V+1)xV, which requires O(V^2) space. Additionally, the program creates a vector of edges, which takes up O(E) space, where E is the number of edges in the graph. However, in this particular implementation, the number of edges is not directly stored, and it is not clear whether all edges are actually added to the vector. Therefore, the space complexity is mainly determined by the size of the dp array, which is O(V^2).
We use cookies to ensure you have the best browsing experience on our website. By using our site, you
acknowledge that you have read and understood our
Cookie Policy &
Privacy Policy
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.