Given a Graph, count number of triangles in it. The graph is can be directed or undirected.
Example:
Input: digraph[V][V] = { {0, 0, 1, 0},
{1, 0, 0, 1},
{0, 1, 0, 0},
{0, 0, 1, 0}
};
Output: 2
Give adjacency matrix represents following
directed graph.

We have discussed a method based on graph trace that works for undirected graphs. In this post a new method is discussed with that is simpler and works for both directed and undirected graphs.
The idea is to use three nested loops to consider every triplet (i, j, k) and check for the above condition (there is an edge from i to j, j to k and k to i)
However in an undirected graph, the triplet (i, j, k) can be permuted to give six combination (See previous post for details). Hence we divide the total count by 6 to get the actual number of triangles.
In case of directed graph, the number of permutation would be 3 (as order of nodes becomes relevant). Hence in this case the total number of triangles will be obtained by dividing total count by 3. For example consider the directed graph given below
Following is the implementation.
C++
#include<bits/stdc++.h>
#define V 4
using namespace std;
int countTriangle( int graph[V][V],
bool isDirected)
{
int count_Triangle = 0;
for ( int i = 0; i < V; i++)
{
for ( int j = 0; j < V; j++)
{
for ( int k = 0; k < V; k++)
{
if (graph[i][j] && graph[j][k]
&& graph[k][i])
count_Triangle++;
}
}
}
isDirected? count_Triangle /= 3 :
count_Triangle /= 6;
return count_Triangle;
}
int main()
{
int graph[][V] = { {0, 1, 1, 0},
{1, 0, 1, 1},
{1, 1, 0, 1},
{0, 1, 1, 0}
};
int digraph[][V] = { {0, 0, 1, 0},
{1, 0, 0, 1},
{0, 1, 0, 0},
{0, 0, 1, 0}
};
cout << "The Number of triangles in undirected graph : "
<< countTriangle(graph, false );
cout << "\n\nThe Number of triangles in directed graph : "
<< countTriangle(digraph, true );
return 0;
}
|
Java
import java.io.*;
class GFG {
int V = 4 ;
int countTriangle( int graph[][],
boolean isDirected)
{
int count_Triangle = 0 ;
for ( int i = 0 ; i < V; i++)
{
for ( int j = 0 ; j < V; j++)
{
for ( int k= 0 ; k<V; k++)
{
if (graph[i][j] == 1 &&
graph[j][k] == 1 &&
graph[k][i] == 1 )
count_Triangle++;
}
}
}
if (isDirected == true )
{
count_Triangle /= 3 ;
}
else
{
count_Triangle /= 6 ;
}
return count_Triangle;
}
public static void main(String args[])
{
int graph[][] = {{ 0 , 1 , 1 , 0 },
{ 1 , 0 , 1 , 1 },
{ 1 , 1 , 0 , 1 },
{ 0 , 1 , 1 , 0 }
};
int digraph[][] = { { 0 , 0 , 1 , 0 },
{ 1 , 0 , 0 , 1 },
{ 0 , 1 , 0 , 0 },
{ 0 , 0 , 1 , 0 }
};
GFG obj = new GFG();
System.out.println( "The Number of triangles " +
"in undirected graph : " +
obj.countTriangle(graph, false ));
System.out.println( "\n\nThe Number of triangles" +
" in directed graph : " +
obj.countTriangle(digraph, true ));
}
}
|
Python3
def countTriangle(g, isDirected):
nodes = len (g)
count_Triangle = 0
for i in range (nodes):
for j in range (nodes):
for k in range (nodes):
if (i ! = j and i ! = k
and j ! = k and
g[i][j] and g[j][k]
and g[k][i]):
count_Triangle + = 1
if isDirected:
return count_Triangle / / 3
else : return count_Triangle / / 6
graph = [[ 0 , 1 , 1 , 0 ],
[ 1 , 0 , 1 , 1 ],
[ 1 , 1 , 0 , 1 ],
[ 0 , 1 , 1 , 0 ]]
digraph = [[ 0 , 0 , 1 , 0 ],
[ 1 , 0 , 0 , 1 ],
[ 0 , 1 , 0 , 0 ],
[ 0 , 0 , 1 , 0 ]]
print ( "The Number of triangles in undirected graph : %d" %
countTriangle(graph, False ))
print ( "The Number of triangles in directed graph : %d" %
countTriangle(digraph, True ))
|
C#
using System;
class GFG {
const int V = 4;
static int countTriangle( int [, ] graph, bool isDirected)
{
int count_Triangle = 0;
for ( int i = 0; i < V; i++)
{
for ( int j = 0; j < V; j++)
{
for ( int k = 0; k < V; k++)
{
if (graph[i, j] != 0
&& graph[j, k] != 0
&& graph[k, i] != 0)
count_Triangle++;
}
}
}
if (isDirected != false )
count_Triangle = count_Triangle / 3;
else
count_Triangle = count_Triangle / 6;
return count_Triangle;
}
static void Main()
{
int [, ] graph = new int [4, 4] { { 0, 1, 1, 0 },
{ 1, 0, 1, 1 },
{ 1, 1, 0, 1 },
{ 0, 1, 1, 0 } };
int [, ] digraph = new int [4, 4] { { 0, 0, 1, 0 },
{ 1, 0, 0, 1 },
{ 0, 1, 0, 0 },
{ 0, 0, 1, 0 } };
Console.Write( "The Number of triangles"
+ " in undirected graph : "
+ countTriangle(graph, false ));
Console.Write( "\n\nThe Number of "
+ "triangles in directed graph : "
+ countTriangle(digraph, true ));
}
}
|
PHP
<?php
$V = 4;
function countTriangle( $graph ,
$isDirected )
{
global $V ;
$count_Triangle = 0;
for ( $i = 0; $i < $V ; $i ++)
{
for ( $j = 0; $j < $V ; $j ++)
{
for ( $k = 0; $k < $V ; $k ++)
{
if ( $graph [ $i ][ $j ] and $graph [ $j ][ $k ]
and $graph [ $k ][ $i ])
$count_Triangle ++;
}
}
}
$isDirected ? $count_Triangle /= 3 :
$count_Triangle /= 6;
return $count_Triangle ;
}
$graph = array ( array (0, 1, 1, 0),
array (1, 0, 1, 1),
array (1, 1, 0, 1),
array (0, 1, 1, 0));
$digraph = array ( array (0, 0, 1, 0),
array (1, 0, 0, 1),
array (0, 1, 0, 0),
array (0, 0, 1, 0));
echo "The Number of triangles in undirected graph : "
, countTriangle( $graph , false);
echo "\nThe Number of triangles in directed graph : "
, countTriangle( $digraph , true);
?>
|
Javascript
<script>
let V = 4;
function countTriangle(graph, isDirected)
{
let count_Triangle = 0;
for (let i = 0; i < V; i++)
{
for (let j = 0; j < V; j++)
{
for (let k = 0; k < V; k++)
{
if (graph[i][j] && graph[j][k] &&
graph[k][i])
count_Triangle++;
}
}
}
isDirected ? count_Triangle /= 3 :
count_Triangle /= 6;
return count_Triangle;
}
let graph = [ [ 0, 1, 1, 0 ],
[ 1, 0, 1, 1 ],
[ 1, 1, 0, 1 ],
[ 0, 1, 1, 0 ] ];
let digraph = [ [ 0, 0, 1, 0 ],
[ 1, 0, 0, 1 ],
[ 0, 1, 0, 0 ],
[ 0, 0, 1, 0 ] ];
document.write( "The Number of triangles " +
"in undirected graph : " +
countTriangle(graph, false ) +
"</br></br>" );
document.write( "The Number of triangles " +
"in directed graph : " +
countTriangle(digraph, true ));
</script>
|
Output
The Number of triangles in undirected graph : 2
The Number of triangles in directed graph : 2
Comparison of this approach with previous approach:
Advantages:
- No need to calculate Trace.
- Matrix- multiplication is not required.
- Auxiliary matrices are not required hence optimized in space.
- Works for directed graphs.
Disadvantages:
- The time complexity is O(n3) and can’t be reduced any further.
If you like GeeksforGeeks and would like to contribute, you can also write an article and mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
21 Jan, 2022
Like Article
Save Article