📌  相关文章
📜  对的数量,以使对之间的路径具有两个顶点A和B

📅  最后修改于: 2021-04-22 09:34:26             🧑  作者: Mango

给定一个无向连通图和两个顶点AB ,任务是找到顶点对{X,Y}的数量,以使从XY的任何路径都包含顶点AB。

笔记:

  • {X,Y}等效于{Y,X}。
  • X!= A,X!= B,Y!= A和Y!= B.

例子:

方法:

  • 对于给定图,如果对于任意一对{X,Y} ,如果它们之间存在给定顶点AB以外的其他路径,则最终答案中将不包括这两个顶点。那是因为我们需要对的数量,以使这些对中的任何路径都包含顶点AB。
  • 因此,我们对成对的顶点{X,Y}感兴趣,这样删除顶点A (从B到)会断开从X到Y的连接,而删除顶点B (从A到去)则会断开从X到Y的连接。是的
  • 换句话说如果X和Y都在删除A和删除B时都属于图的不同组件,那么{X,Y}对就使我们感兴趣。

因此,为了找到上述对,请执行以下步骤:

  • 考虑一个随机有向连接图,其中一些互连的节点组连接到A,而一些互连的节点组连接到B。 AB之间可能有也可能没有节点。
  • 如果我们同时删除AB怎么办?然后,图形可以断开连接或保持连接状态。
  • 如果图保持连接状态,则不存在一对顶点,因为图中所有{X,Y}对都存在其他路径,其中没有顶点AB。
  • 如果图形断开连接,则出现两种情况:
    1. 删除顶点A和B时,图形将转换为两个断开的组件。
    2. 删除顶点A和B时,图形将转换为三个断开的组件。

如果在移除顶点AB时,图形被转换为两个断开的分量,则出现三种情况:

  1. 当有一组互连的节点连接到顶点A时,一些独立的节点连接到A和B,而顶点B是图的叶节点:

    显然,在上面的图中,当从顶点A和顶点B中删除该图时,该图将转换为两个不同的分量。并且,可以丢弃任何分量,因为一个分量的顶点可以不经过顶点B而转到任何其他分量的顶点。因此,不存在任何一对。
  2. 当有一组互连的节点连接到顶点B时,一些独立的节点连接到A和B,而顶点A是图的叶节点:

    显然,在上面的图中,当从顶点A和顶点B中删除该图时,该图将转换为两个不同的分量。并且,任何分量都可以被丢弃,因为一个分量的顶点可能会经过任何其他分量的顶点而不会遍历顶点A。因此,不存在任何一对。
  3. 当顶点A和顶点B之间没有节点,并且顶点AB都不是图的叶节点时:

    显然,在上面的图中,当从顶点A和顶点B中删除该图时,该图将转换为两个不同的分量。在此,一个组件的任意一个顶点可以与另一组件的任意一个顶点配对。因此,该图中的对数成为组件1和组件2中互连节点数量的乘积

如果在删除顶点A和B时,图形被转换为三个断开的分量,则只会出现一种情况:

  1. 当有一组互连的节点连接到顶点A,顶点B时,在顶点A和顶点B之间还有另一组节点,并且顶点A和B都不是叶节点:

    在这种情况下,由于上述原因,顶点A和顶点B之间的分量可以被丢弃。并且,一旦将其丢弃,它就是两分量图中的情况3。可以使用相同的概念来找到顶点数。

因此,可以通过以下步骤实现上述想法:

  1. 使用向量STL将图形存储为邻接表。
  2. 运行DFS,以便我们像修复顶点B一样固定顶点B。这可以使用DFS函数的基本条件来完成,即在到达顶点B时返回调用。
  3. 计算除去BA不能到达的顶点。
  4. 通过固定顶点A并计算除去顶点AB不能达到的顶点数量,重复上述两个步骤。
  5. 将两个计数存储在两个不同的变量中。这表示在删除B之后再删除A时首先设置的顶点数。
  6. 将两个计数相乘是必需的答案。

下面是上述方法的实现:

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)