查找具有给定节点 K 的最大公共节点数的节点
给定一个由N个节点和一个数组edges[][]组成的图,表示从edges[i][0]到edges[i][1]的边。给定一个节点K ,任务是找到具有最大公共节点数的节点K 。
例子:
Input: K = 1, N = 4, edges = {{1, 2}, {1, 3}, {2, 3}, {3, 4}, {2, 4}}
Output: 4
Explanation: The graph formed by given edges is shown below.
Given K = 1, Adjacent nodes to all the nodes are below
1: 2, 3
2: 1, 3, 4
3: 1, 2, 4
4: 2, 3
Clearly node 4 is having maximum common nodes with node 1. Therefore, 4 is the answer.
Input: K = 2, N = 3, edges = {{1, 2}, {1, 3}, {2, 3}}
Output: 3
方法:这个问题可以通过使用广度优先搜索来解决。请按照以下步骤解决给定的问题。
- 这个想法是使用 BFS 和源作为给定节点(级别 0)。
- 将给定节点的所有邻居存储在一个列表中,比如al1 (级别 1)
- 现在维护另一个列表al2并将每个级别存储在 BFS 中,并使用al2计算al1的公共元素。
- 维护变量max以维护最大普通朋友的计数,另一个变量mostAppnode存储给定问题的答案。
- 返回mostAppnode 。
下面是上述方法的实现:
C++
// C++ implementation of above approach
#include
using namespace std;
// No. of nodes
int V;
// Adjacency Lists
vector > adj;
// Neighbours of given node stored in al1
vector al1;
void create_Graph(int v)
{
V = v;
adj = {};
for (int i = 0; i < v; ++i)
adj.push_back({});
}
// Function to add an edge into the graph
void addEdge(int v, int w)
{
adj[(v - 1)].push_back(w - 1);
adj[(w - 1)].push_back(v - 1);
}
// find element in queue
bool contains(queue q, int n)
{
while (q.size()) {
if (q.front() == n)
return 1;
q.pop();
}
return false;
}
int BFS(int s)
{
// Mark all the vertices as not visited
// (By default set as false)
bool visited[V] = { 0 };
// Create a queue for BFS
queue queue;
// Mark the current node
// as visited and enqueue it
visited[s] = true;
queue.push(s);
int c = 0;
// Max common nodes with given node
int max = 0;
int mostAppnode = 0;
// To store common nodes
int count = 0;
while (queue.size() != 0) {
// Dequeue a vertex from queue
s = queue.front();
queue.pop();
// Get all adjacent nodes
// of the dequeued node
// If a adjacent has
// not been visited, then
// mark it visited and enqueue it
c++;
vector al2;
int i = 0;
while (i < adj[s].size()) {
int n = adj[s][i];
if (c == 1)
al1.push_back(n);
else
al2.push_back(n);
// If node is not
// visited and also not
// present in queue.
if (!visited[n] && !contains(queue, n)) {
visited[n] = true;
queue.push(n);
}
i++;
}
if (al2.size() != 0) {
for (int frnd : al2) {
if (find(al1.begin(), al1.end(), frnd)
!= al1.end())
count++;
}
if (count > max) {
max = count;
mostAppnode = s;
}
}
}
if (max != 0)
return mostAppnode + 1;
else
return -1;
}
// Driver Code
int main()
{
int N = 4;
create_Graph(4);
addEdge(1, 2);
addEdge(1, 3);
addEdge(2, 3);
addEdge(3, 4);
addEdge(2, 4);
int K = 1;
cout << (BFS(K - 1)) << endl;
}
// This code is contributed by rj13to.
Java
// Java implementation of above approach
import java.io.*;
import java.util.*;
class Graph {
// No. of nodes
private int V;
// Adjacency Lists
private ArrayList > adj;
// Neighbours of given node stored in al1
ArrayList al1 = new ArrayList<>();
// Constructor
Graph(int v)
{
V = v;
adj = new ArrayList<>();
for (int i = 0; i < v; ++i)
adj.add(new ArrayList());
}
// Function to add an edge into the graph
void addEdge(int v, int w)
{
adj.get(v - 1).add(w - 1);
adj.get(w - 1).add(v - 1);
}
private int BFS(int s)
{
// Mark all the vertices as not visited
// (By default set as false)
boolean visited[] = new boolean[V];
// Create a queue for BFS
LinkedList queue
= new LinkedList();
// Mark the current node
// as visited and enqueue it
visited[s] = true;
queue.add(s);
int c = 0;
// Max common nodes with given node
int max = 0;
int mostAppnode = 0;
// To store common nodes
int count = 0;
while (queue.size() != 0) {
// Dequeue a vertex from queue
s = queue.poll();
// Get all adjacent nodes
// of the dequeued node
// If a adjacent has
// not been visited, then
// mark it visited and enqueue it
c++;
ArrayList al2
= new ArrayList<>();
Iterator i
= adj.get(s).listIterator();
while (i.hasNext()) {
int n = i.next();
if (c == 1)
al1.add(n);
else
al2.add(n);
// If node is not
// visited and also not
// present in queue.
if (!visited[n]
&& !queue.contains(n)) {
visited[n] = true;
queue.add(n);
}
}
if (al2.size() != 0) {
for (int frnd : al2) {
if (al1.contains(frnd))
count++;
}
if (count > max) {
max = count;
mostAppnode = s;
}
}
}
if (max != 0)
return mostAppnode + 1;
else
return -1;
}
// Driver Code
public static void main(String[] args)
{
int N = 4;
Graph g = new Graph(4);
g.addEdge(1, 2);
g.addEdge(1, 3);
g.addEdge(2, 3);
g.addEdge(3, 4);
g.addEdge(2, 4);
int K = 1;
System.out.println(g.BFS(K - 1));
}
}
Python3
# python implementation of above approach
# Neighbours of given node stored in al1
al1 = []
# Function to add an edge into the graph
def addEdge(v, w, adj):
adj[v - 1].append(w - 1)
adj[w - 1].append(v - 1)
def BFS(s, adj, V):
# Mark all the vertices as not visited
# (By default set as false)
visited = [False] * V
# Create a queue for BFS
queue = []
# Mark the current node
# as visited and enqueue it
visited[s] = True
queue.append(s)
c = 0
# Max common nodes with given node
max = 0
mostAppnode = 0
# To store common nodes
count = 0
while (len(queue) != 0):
# Dequeue a vertex from queue
s = queue[0]
queue.pop(0)
# Get all adjacent nodes
# of the dequeued node
# If a adjacent has
# not been visited, then
# mark it visited and enqueue it
c += 1
al2 = []
for i in adj[s]:
n = i
if (c == 1):
al1.append(n)
else:
al2.append(n)
# If node is not
# visited and also not
# present in queue.
is_contained = False
if(n in queue):
is_contained = True
if ((visited[n] == False) and (is_contained == False)):
visited[n] = True
queue.append(n)
if (len(al2) != 0):
for frnd in al2:
if (frnd in al1):
count += 1
if (count > max):
max = count
mostAppnode = s
if (max != 0):
return mostAppnode + 1
else:
return -1
# Driver Code
N = 4
# list to store connections
adj = [[]]*N
addEdge(1, 2, adj)
addEdge(1, 3, adj)
addEdge(2, 3, adj)
addEdge(3, 4, adj)
addEdge(2, 4, adj)
K = 1
print(BFS(K - 1, adj, N))
# This code is contributed by rj13to.
输出
4
时间复杂度: O(V*V),BFS 需要 O(V+E) 时间,但是寻找 al1 和 al2 之间的共同元素需要 O(V*V) 时间。
辅助空间: O(V)