给定一个无向连通图和两个顶点A和B ,任务是找到顶点对{X,Y}的数量,以使从X到Y的任何路径都包含顶点A和B。
笔记:
- {X,Y}等效于{Y,X}。
- X!= A,X!= B,Y!= A和Y!= B.
例子:
For the above graph:
Input: A = 3, B = 5
Output:4
Explanation:
There are four pairs { X, Y } such that all the paths from the source X to the destination Y contain the vertices A, B. They are:
{1, 6}, {1, 7}, {2, 6} and {2, 7}.
For the above graph:
Input: A = 2, B = 1
Output: 1
Explanation:
There is only one pair { X, Y } such that all the paths from the source X to the destination Y contain the vertices A, B. That is:
{4, 3}.
方法:
- 对于给定图,如果对于任意一对{X,Y} ,如果它们之间存在除给定顶点A和B之外的其他路径,则最终答案中将不包括这两个顶点。那是因为我们需要对的数量,以使这些对中的任何路径都包含顶点A和B。
- 因此,我们对成对的顶点{X,Y}感兴趣,因此删除顶点A (从B到)会断开从X到Y的连接,而删除顶点B (从A到去)则会断开从X到Y的连接。是的
- 换句话说,如果X和Y都在删除A和删除B时都属于图的不同组件,那么{X,Y}对就使我们感兴趣。
因此,为了找到上述对,请执行以下步骤:
- 考虑一个随机有向连接图,其中一些互连的节点组连接到A,而一些互连的节点组连接到B。 A和B之间可能有也可能没有节点。
- 如果我们同时删除A和B怎么办?然后,图形可以断开连接或保持连接状态。
- 如果图保持连接状态,则不存在一对顶点,因为图中所有{X,Y}对都存在其他路径,其中没有顶点A和B。
- 如果图形断开连接,则出现两种情况:
- 删除顶点A和B时,图形将转换为两个断开的组件。
- 删除顶点A和B时,图形将转换为三个断开的组件。
如果在删除顶点A和B时,图形被转换为两个断开的分量,则出现三种情况:
- 当有一组互连的节点连接到顶点A时,一些独立的节点连接到A和B,而顶点B是图的叶节点:
显然,在上面的图中,当从顶点A和顶点B中删除该图时,该图将转换为两个不同的分量。并且,可以丢弃任何分量,因为一个分量的顶点可以不经过顶点B而转到任何其他分量的顶点。因此,不存在任何一对。 - 当有一组互连的节点连接到顶点B时,一些独立的节点连接到A和B,而顶点A是图的叶节点:
显然,在上面的图中,当从顶点A和顶点B中删除该图时,该图将转换为两个不同的分量。并且,可以丢弃任何组件,因为一个组件的顶点可能会经过任何其他组件的顶点而不会遍历顶点A。因此,不存在任何一对。 - 当顶点A和顶点B之间没有节点,并且顶点A和B都不是图的叶节点时:
显然,在上面的图中,当从顶点A和顶点B中删除该图时,该图将转换为两个不同的分量。在此,一个组件的任意一个顶点可以与另一组件的任意一个顶点配对。因此,该图中的对数成为组件1和组件2中互连节点数量的乘积。
如果在删除顶点A和B时,图形被转换为三个断开的分量,则只会出现一种情况:
- 当有一组互连的节点连接到顶点A,顶点B时,在顶点A和顶点B之间还有另一组节点,并且顶点A和B都不是叶节点:
在这种情况下,由于上述原因,顶点A和顶点B之间的分量可以被丢弃。并且,一旦将其丢弃,它就是两分量图中的情况3。可以使用相同的概念来找到顶点数。
因此,可以通过以下步骤实现上述想法:
- 使用向量STL将图形存储为邻接表。
- 运行DFS,以便我们像修复顶点B一样固定顶点B。这可以使用DFS函数的基本条件来完成,即在到达顶点B时返回调用。
- 计算除去B后A不能到达的顶点。
- 通过固定顶点A并计算除去顶点A后B不能达到的顶点数量,重复上述两个步骤。
- 将两个计数都存储在两个不同的变量中。这表示在删除B之后再删除A时首先设置的顶点数。
- 将两个计数相乘是必需的答案。
下面是上述方法的实现:
C++
// C++ program to find the number
// of pairs such that the path between
// every pair contains two given vertices
#include
using namespace std;
const int N = 1000001;
int c, n, m, a, b;
// Function to perform DFS on the given graph
// by fixing the a vertex
void dfs(int a, int b, vector v[], int vis[])
{
// To mark a particular vertex as visited
vis[a] = 1;
// Variable to store the count of the
// vertices which can be reached from a
c++;
// Performing the DFS by iterating over
// the visited array
for (auto i : v[a]) {
// If the vertex is not visited
// and removing the vertex b
if (!vis[i] && i != b)
dfs(i, b, v, vis);
}
}
// Function to return the number of pairs
// such that path between any two pairs
// consists the given two vertices A and B
void Calculate(vector v[])
{
// Initializing the visited array
// and assigning it with 0's
int vis[n + 1];
memset(vis, 0, sizeof(vis));
// Initially, the count of vertices is 0
c = 0;
// Performing DFS by removing the vertex B
dfs(a, b, v, vis);
// Count the vertices which cannot be
// reached after removing the vertex B
int ans1 = n - c - 1;
// Again reinitializing the visited array
memset(vis, 0, sizeof(vis));
// Setting the count of vertices to 0 to
// perform the DFS again
c = 0;
// Performing the DFS by removing the vertex A
dfs(b, a, v, vis);
// Count the vertices which cannot be
// reached after removing the vertex A
int ans2 = n - c - 1;
// Multiplying both the vertices set
cout << ans1 * ans2 << "\n";
}
// Driver code
int main()
{
n = 7, m = 7, a = 3, b = 5;
int edges[][2] = { { 1, 2 },
{ 2, 3 },
{ 3, 4 },
{ 4, 5 },
{ 5, 6 },
{ 6, 7 },
{ 7, 5 } };
vector v[n + 1];
// Loop to store the graph
for (int i = 0; i < m; i++) {
v[edges[i][0]].push_back(edges[i][1]);
v[edges[i][1]].push_back(edges[i][0]);
}
Calculate(v);
return 0;
}
Java
// Java program to find the number
// of pairs such that the path between
// every pair contains two given vertices
import java.util.*;
class GFG{
static int N = 1000001;
static int c, n, m, a, b;
// Function to perform DFS on the given graph
// by fixing the a vertex
static void dfs(int a, int b, Vector v[], int vis[])
{
// To mark a particular vertex as visited
vis[a] = 1;
// Variable to store the count of the
// vertices which can be reached from a
c++;
// Performing the DFS by iterating over
// the visited array
for (int i : v[a]) {
// If the vertex is not visited
// and removing the vertex b
if (vis[i] == 0 && i != b)
dfs(i, b, v, vis);
}
}
// Function to return the number of pairs
// such that path between any two pairs
// consists of the given two vertices A and B
static void Calculate(Vector v[])
{
// Initializing the visited array
// and assigning it with 0's
int []vis = new int[n + 1];
Arrays.fill(vis, 0);
// Initially, the count of vertices is 0
c = 0;
// Performing DFS by removing the vertex B
dfs(a, b, v, vis);
// Count the vertices which cannot be
// reached after removing the vertex B
int ans1 = n - c - 1;
// Again reinitializing the visited array
Arrays.fill(vis, 0);
// Setting the count of vertices to 0 to
// perform the DFS again
c = 0;
// Performing the DFS by removing the vertex A
dfs(b, a, v, vis);
// Count the vertices which cannot be
// reached after removing the vertex A
int ans2 = n - c - 1;
// Multiplying both the vertices set
System.out.print(ans1 * ans2+ "\n");
}
// Driver code
public static void main(String[] args)
{
n = 7;
m = 7;
a = 3;
b = 5;
int edges[][] = { { 1, 2 },
{ 2, 3 },
{ 3, 4 },
{ 4, 5 },
{ 5, 6 },
{ 6, 7 },
{ 7, 5 } };
Vector []v = new Vector[n + 1];
for(int i= 0; i <= n; i++) {
v[i] = new Vector();
}
// Loop to store the graph
for (int i = 0; i < m; i++) {
v[edges[i][0]].add(edges[i][1]);
v[edges[i][1]].add(edges[i][0]);
}
Calculate(v);
}
}
// This code is contributed by Rajput-Ji
Python3
# Python 3 program to find the number
# of pairs such that the path between
# every pair contains two given vertices
N = 1000001
c = 0
n = 0
m = 0
a = 0
b = 0
# Function to perform DFS on the given graph
# by fixing the a vertex
def dfs(a,b,v,vis):
global c
# To mark a particular vertex as visited
vis[a] = 1
# Variable to store the count of the
# vertices which can be reached from a
c += 1
# Performing the DFS by iterating over
# the visited array
for i in v[a]:
# If the vertex is not visited
# and removing the vertex b
if (vis[i]==0 and i != b):
dfs(i, b, v, vis)
# Function to return the number of pairs
# such that path between any two pairs
# consists of the given two vertices A and B
def Calculate(v):
global c
# Initializing the visited array
# and assigning it with 0's
vis = [0 for i in range(n + 1)]
# Initially, the count of vertices is 0
c = 0
# Performing DFS by removing the vertex B
dfs(a, b, v, vis)
# Count the vertices which cannot be
# reached after removing the vertex B
ans1 = n - c - 1
# Again reinitializing the visited array
vis = [0 for i in range(len(vis))]
# Setting the count of vertices to 0 to
# perform the DFS again
c = 0
# Performing the DFS by removing the vertex A
dfs(b, a, v, vis)
# Count the vertices which cannot be
# reached after removing the vertex A
ans2 = n - c - 1
# Multiplying both the vertices set
print(ans1 * ans2)
# Driver code
if __name__ == '__main__':
n = 7
m = 7
a = 3
b = 5
edges = [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 5]]
v = [[] for i in range(n + 1)]
# Loop to store the graph
for i in range(m):
v[edges[i][0]].append(edges[i][1])
v[edges[i][1]].append(edges[i][0])
Calculate(v)
# This code is contributed by Surendra_Gangwar
C#
// C# program to find the number
// of pairs such that the path between
// every pair contains two given vertices
using System;
using System.Collections.Generic;
class GFG{
static int N = 1000001;
static int c, n, m, a, b;
// Function to perform DFS on the given graph
// by fixing the a vertex
static void dfs(int a, int b, List []v, int []vis)
{
// To mark a particular vertex as visited
vis[a] = 1;
// Variable to store the count of the
// vertices which can be reached from a
c++;
// Performing the DFS by iterating over
// the visited array
foreach (int i in v[a]) {
// If the vertex is not visited
// and removing the vertex b
if (vis[i] == 0 && i != b)
dfs(i, b, v, vis);
}
}
// Function to return the number of pairs
// such that path between any two pairs
// consists of the given two vertices A and B
static void Calculate(List []v)
{
// Initializing the visited array
// and assigning it with 0's
int []vis = new int[n + 1];
for(int i = 0; i < n + 1; i++)
vis[i] = 0;
// Initially, the count of vertices is 0
c = 0;
// Performing DFS by removing the vertex B
dfs(a, b, v, vis);
// Count the vertices which cannot be
// reached after removing the vertex B
int ans1 = n - c - 1;
// Again reinitializing the visited array
for(int i = 0; i < n + 1; i++)
vis[i] = 0;
// Setting the count of vertices to 0 to
// perform the DFS again
c = 0;
// Performing the DFS by removing the vertex A
dfs(b, a, v, vis);
// Count the vertices which cannot be
// reached after removing the vertex A
int ans2 = n - c - 1;
// Multiplying both the vertices set
Console.Write(ans1 * ans2+ "\n");
}
// Driver code
public static void Main(String[] args)
{
n = 7;
m = 7;
a = 3;
b = 5;
int [,]edges = { { 1, 2 },
{ 2, 3 },
{ 3, 4 },
{ 4, 5 },
{ 5, 6 },
{ 6, 7 },
{ 7, 5 } };
List []v = new List[n + 1];
for(int i= 0; i <= n; i++) {
v[i] = new List();
}
// Loop to store the graph
for (int i = 0; i < m; i++) {
v[edges[i,0]].Add(edges[i,1]);
v[edges[i,1]].Add(edges[i,0]);
}
Calculate(v);
}
}
// This code is contributed by Princi Singh
4
时间复杂度分析:
- 在此,DFS执行两次。因此,总体时间复杂度为O(V + E) 。
如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。