树中两条不相交路径的最大乘积

给定一棵具有N个节点(和N-1条边)的无向连通树,我们需要在这棵树中找到两条不相交且其长度乘积最大的路径。

null

例如:

In first tree two paths which are non-intersecting
and have highest product are, 1-2 and 3-4, so answer
is 1*1 = 1
In second tree two paths which are non-intersecting 
and has highest product are, 1-3-5  and  7-8-6-2 
(or 4-8-6-2), so answer is 3*2 = 6

Maximum product of two non-intersecting paths in a tree

我们可以通过以下步骤通过树的深度优先搜索来解决这个问题,因为树是连接的,路径是不相交的,如果我们选择任何一对这样的路径,必须有第三条路径,连接这两条路径,如果我们从第三条路径移除一条边,那么树将被分成两个部分——一个包含第一条路径,另一个包含第二条路径。这一观察结果为我们提供了一种算法:迭代边缘;对于每条边,删除它,在两个连接的组件中找到路径的长度,并将这些路径的长度相乘。树中路径的长度可以通过修改的深度优先搜索找到,我们将在每个邻居处调用最大路径,并将返回的两个最大长度相加,这将是当前节点上的子树的最大路径长度。

实施细节: 输入是一棵树,但其中没有指定的根,因为我们只有边的集合。树被表示为无向图。我们遍历邻接列表。对于每条边,我们都会在其两侧找到最大长度的路径(删除边后)。我们跟踪因边缘去除而产生的最大产量。

C++

// C++ program to find maximum product of two
// non-intersecting paths
#include <bits/stdc++.h>
using namespace std;
/*  Returns maximum length path in subtree rooted
at u after removing edge connecting u and v */
int dfs(vector< int > g[], int & curMax, int u, int v)
{
// To find lengths of first and second maximum
// in subtrees. currMax is to store overall
// maximum.
int max1 = 0, max2 = 0, total = 0;
//  loop through all neighbors of u
for ( int i = 0; i < g[u].size(); i++)
{
//  if neighbor is v, then skip it
if (g[u][i] == v)
continue ;
//  call recursively with current neighbor as root
total = max(total, dfs(g, curMax, g[u][i], u));
//  get max from one side and update
if (curMax > max1)
{
max2 = max1;
max1 = curMax;
}
else
max2 = max(max2, curMax);
}
// store total length by adding max
// and second max
total = max(total, max1 + max2);
// update current max by adding 1, i.e.
// current node is included
curMax = max1 + 1;
return total;
}
// method returns maximum product of length of
// two non-intersecting paths
int maxProductOfTwoPaths(vector< int > g[], int N)
{
int res = INT_MIN;
int path1, path2;
// one by one removing all edges and calling
// dfs on both subtrees
for ( int i = 1; i < N+2; i++)
{
for ( int j = 0; j < g[i].size(); j++)
{
// calling dfs on subtree rooted at
// g[i][j], excluding edge from g[i][j]
// to i.
int curMax = 0;
path1 = dfs(g, curMax, g[i][j], i);
//  calling dfs on subtree rooted at
// i, edge from i to g[i][j]
curMax = 0;
path2 = dfs(g, curMax, i, g[i][j]);
res = max(res, path1 * path2);
}
}
return res;
}
// Utility function to add an undirected edge (u,v)
void addEdge(vector< int > g[], int u, int v)
{
g[u].push_back(v);
g[v].push_back(u);
}
//  Driver code to test above methods
int main()
{
int edges[][2] = {{1, 8}, {2, 6}, {3, 1},
{5, 3}, {7, 8}, {8, 4},
{8, 6} };
int N = sizeof (edges)/ sizeof (edges[0]);
// there are N edges, so +1 for nodes and +1
// for 1-based indexing
vector< int > g[N + 2];
for ( int i = 0; i < N; i++)
addEdge(g, edges[i][0], edges[i][1]);
cout << maxProductOfTwoPaths(g, N) << endl;
return 0;
}


JAVA

// Java program to find maximum product
// of two non-intersecting paths
import java.util.*;
class GFG{
static int curMax;
// Returns maximum length path in
// subtree rooted at u after
// removing edge connecting u and v
static int dfs(Vector<Integer> g[],
int u, int v)
{
// To find lengths of first and
// second maximum in subtrees.
// currMax is to store overall
// maximum.
int max1 = 0 , max2 = 0 , total = 0 ;
// Loop through all neighbors of u
for ( int i = 0 ; i < g[u].size(); i++)
{
// If neighbor is v, then skip it
if (g[u].get(i) == v)
continue ;
// Call recursively with current
// neighbor as root
total = Math.max(total, dfs(
g, g[u].get(i), u));
// Get max from one side and update
if (curMax > max1)
{
max2 = max1;
max1 = curMax;
}
else
max2 = Math.max(max2, curMax);
}
// Store total length by adding max
// and second max
total = Math.max(total, max1 + max2);
// Update current max by adding 1, i.e.
// current node is included
curMax = max1 + 1 ;
return total;
}
// Method returns maximum product of
// length of two non-intersecting paths
static int maxProductOfTwoPaths(Vector<Integer> g[],
int N)
{
int res = Integer.MIN_VALUE;
int path1, path2;
// One by one removing all edges and
// calling dfs on both subtrees
for ( int i = 1 ; i < N + 2 ; i++)
{
for ( int j = 0 ; j < g[i].size(); j++)
{
// Calling dfs on subtree rooted at
// g[i][j], excluding edge from g[i][j]
// to i.
curMax = 0 ;
path1 = dfs(g, g[i].get(j), i);
// Calling dfs on subtree rooted at
// i, edge from i to g[i][j]
curMax = 0 ;
path2 = dfs(g,i, g[i].get(j));
res = Math.max(res, path1 * path2);
}
}
return res;
}
// Utility function to add an
// undirected edge (u,v)
static void addEdge(Vector<Integer> g[],
int u, int v)
{
g[u].add(v);
g[v].add(u);
}
//  Driver code
public static void main(String[] args)
{
int edges[][] = { { 1 , 8 }, { 2 , 6 },
{ 3 , 1 }, { 5 , 3 },
{ 7 , 8 }, { 8 , 4 },
{ 8 , 6 } };
int N = edges.length;
// There are N edges, so +1 for nodes
// and +1 for 1-based indexing
@SuppressWarnings ( "unchecked" )
Vector<Integer> []g = new Vector[N + 2 ];
for ( int i = 0 ; i < g.length; i++)
g[i] = new Vector<Integer>();
for ( int i = 0 ; i < N; i++)
addEdge(g, edges[i][ 0 ], edges[i][ 1 ]);
System.out.print(maxProductOfTwoPaths(g, N) + "" );
}
}
// This code is contributed by Princi Singh


Python3

# Python3 program to find maximum product of two
# non-intersecting paths
# Returns maximum length path in subtree rooted
# at u after removing edge connecting u and v
def dfs(g, curMax, u, v):
# To find lengths of first and second maximum
# in subtrees. currMax is to store overall
# maximum.
max1 = 0
max2 = 0
total = 0
# loop through all neighbors of u
for i in range ( len (g[u])):
# if neighbor is v, then skip it
if (g[u][i] = = v):
continue
# call recursively with current neighbor as root
total = max (total, dfs(g, curMax, g[u][i], u))
# get max from one side and update
if (curMax[ 0 ] > max1):
max2 = max1
max1 = curMax[ 0 ]
else :
max2 = max (max2, curMax[ 0 ])
# store total length by adding max
# and second max
total = max (total, max1 + max2)
# update current max by adding 1, i.e.
# current node is included
curMax[ 0 ] = max1 + 1
return total
# method returns maximum product of length of
# two non-intersecting paths
def maxProductOfTwoPaths(g, N):
res = - 999999999999
path1, path2 = None , None
# one by one removing all edges and calling
# dfs on both subtrees
for i in range (N):
for j in range ( len (g[i])):
# calling dfs on subtree rooted at
# g[i][j], excluding edge from g[i][j]
# to i.
curMax = [ 0 ]
path1 = dfs(g, curMax, g[i][j], i)
# calling dfs on subtree rooted at
# i, edge from i to g[i][j]
curMax = [ 0 ]
path2 = dfs(g, curMax, i, g[i][j])
res = max (res, path1 * path2)
return res
# Utility function to add an undirected edge (u,v)
def addEdge(g, u, v):
g[u].append(v)
g[v].append(u)
# Driver code
if __name__ = = '__main__' :
edges = [[ 1 , 8 ], [ 2 , 6 ], [ 3 , 1 ], [ 5 , 3 ], [ 7 , 8 ], [ 8 , 4 ], [ 8 , 6 ]]
N = len (edges)
# there are N edges, so +1 for nodes and +1
# for 1-based indexing
g = [[] for i in range (N + 2 )]
for i in range (N):
addEdge(g, edges[i][ 0 ], edges[i][ 1 ])
print (maxProductOfTwoPaths(g, N))
# This code is contributed by PranchalK


C#

// C# program to find maximum product
// of two non-intersecting paths
using System;
using System.Collections.Generic;
public class GFG
{
static int curMax;
// Returns maximum length path in
// subtree rooted at u after
// removing edge connecting u and v
static int dfs(List< int > []g,
int u, int v)
{
// To find lengths of first and
// second maximum in subtrees.
// currMax is to store overall
// maximum.
int max1 = 0, max2 = 0, total = 0;
// Loop through all neighbors of u
for ( int i = 0; i < g[u].Count; i++)
{
// If neighbor is v, then skip it
if (g[u][i] == v)
continue ;
// Call recursively with current
// neighbor as root
total = Math.Max(total, dfs(
g, g[u][i], u));
// Get max from one side and update
if (curMax > max1)
{
max2 = max1;
max1 = curMax;
}
else
max2 = Math.Max(max2, curMax);
}
// Store total length by adding max
// and second max
total = Math.Max(total, max1 + max2);
// Update current max by adding 1, i.e.
// current node is included
curMax = max1 + 1;
return total;
}
// Method returns maximum product of
// length of two non-intersecting paths
static int maxProductOfTwoPaths(List< int > []g,
int N)
{
int res = int .MinValue;
int path1, path2;
// One by one removing all edges and
// calling dfs on both subtrees
for ( int i = 1; i < N + 2; i++)
{
for ( int j = 0; j < g[i].Count; j++)
{
// Calling dfs on subtree rooted at
// g[i,j], excluding edge from g[i,j]
// to i.
curMax = 0;
path1 = dfs(g, g[i][j], i);
// Calling dfs on subtree rooted at
// i, edge from i to g[i,j]
curMax = 0;
path2 = dfs(g,i, g[i][j]);
res = Math.Max(res, path1 * path2);
}
}
return res;
}
// Utility function to add an
// undirected edge (u,v)
static void addEdge(List< int > []g,
int u, int v)
{
g[u].Add(v);
g[v].Add(u);
}
//  Driver code
public static void Main(String[] args)
{
int [,]edges = { { 1, 8 }, { 2, 6 },
{ 3, 1 }, { 5, 3 },
{ 7, 8 }, { 8, 4 },
{ 8, 6 } };
int N = edges.GetLength(0);
// There are N edges, so +1 for nodes
// and +1 for 1-based indexing
List< int > []g = new List< int >[N + 2];
for ( int i = 0; i < g.Length; i++)
g[i] = new List< int >();
for ( int i = 0; i < N; i++)
addEdge(g, edges[i,0], edges[i,1]);
Console.Write(maxProductOfTwoPaths(g, N) + "" );
}
}
// This code is contributed by aashish1995


Javascript

<script>
// Javascript program to find maximum product of two
// non-intersecting paths
let curMax;
// Returns maximum length path in
// subtree rooted at u after
// removing edge connecting u and v
function dfs(g, u, v)
{
// To find lengths of first and
// second maximum in subtrees.
// currMax is to store overall
// maximum.
let max1 = 0, max2 = 0, total = 0;
// Loop through all neighbors of u
for (let i = 0; i < g[u].length; i++)
{
// If neighbor is v, then skip it
if (g[u][i] == v)
continue ;
// Call recursively with current
// neighbor as root
total = Math.max(total, dfs(
g, g[u][i], u));
// Get max from one side and update
if (curMax > max1)
{
max2 = max1;
max1 = curMax;
}
else
max2 = Math.max(max2, curMax);
}
// Store total length by adding max
// and second max
total = Math.max(total, max1 + max2);
// Update current max by adding 1, i.e.
// current node is included
curMax = max1 + 1;
return total;
}
// Method returns maximum product of
// length of two non-intersecting paths
function maxProductOfTwoPaths(g, N)
{
let res = Number.MIN_VALUE;
let path1, path2;
// One by one removing all edges and
// calling dfs on both subtrees
for (let i = 1; i < N + 2; i++)
{
for (let j = 0; j < g[i].length; j++)
{
// Calling dfs on subtree rooted at
// g[i,j], excluding edge from g[i,j]
// to i.
curMax = 0;
path1 = dfs(g, g[i][j], i);
// Calling dfs on subtree rooted at
// i, edge from i to g[i,j]
curMax = 0;
path2 = dfs(g,i, g[i][j]);
res = Math.max(res, path1 * path2);
}
}
return res;
}
// Utility function to add an
// undirected edge (u,v)
function addEdge(g, u, v)
{
g[u].push(v);
g[v].push(u);
}
let edges = [ [ 1, 8 ], [ 2, 6 ],
[ 3, 1 ], [ 5, 3 ],
[ 7, 8 ], [ 8, 4 ],
[ 8, 6 ] ];
let N = edges.length;
// There are N edges, so +1 for nodes
// and +1 for 1-based indexing
let g = [];
for (let i = 0; i < N + 2; i++)
{
g.push([]);
}
for (let i = 0; i < g.length; i++)
g[i] = [];
for (let i = 0; i < N; i++)
addEdge(g, edges[i][0], edges[i][1]);
document.write(maxProductOfTwoPaths(g, N) + "</br>" );
// This code is contributed by divyesh072019.
</script>


输出:

6

本文由 乌特卡什·特里维迪 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄去评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享