给定一个有V个顶点和E 个边的有向无环图,任务是为图的每个顶点找到一组主导顶点。
What are Dominators in Graph Theory:
In control flow graphs a vertex V1 is the dominator of another vertex V2 if all the paths from the source vertex (in this case the vertex ‘0’) to the vertex V2 passes through V1. By definition, every vertex is one of its own dominators.
例子:
Input: V = 5, E = 5, adj[][] = {{0, 1}, {0, 2}, {1, 3}, {2, 3}, {3, 4}}
Output:
Dominating set of vertex: 0 –> 0
Dominating set of vertex: 1 –> 0 1
Dominating set of vertex: 2 –> 0 2
Dominating set of vertex: 3 –> 0 3
Dominating set of vertex: 4 –> 0 3 4
Explanation:
0
/ \
1 2
\ /
3
|
4
Here 0 is the entry node, so its dominator is 0 itself.
Only one path exists between (0, 1) so the dominators of 1 are 0, 1.
Only one path exists between (0, 2) so the dominators of 2 are 0, 2.
There are 2 paths between(0, 3) having only 0, 3 in common.
From (0, 4) there are 2 paths (0 1 3 4) and (0 2 3 4) with 0, 3 and 4 common.
Input: V = 4, E = 3, adj[][] = {{0, 1}, {0, 2}, {3, 2}}
Output:
Dominating set of vertex: 0 –> 0
Dominating set of vertex: 1 –> 0 1
Dominating set of vertex: 2 –> 0 2
Dominating set of vertex: 3 –> 0 2 3
方法:想法是执行 DFS 并维护一组每个顶点的所有支配者。请按照以下步骤解决问题:
- 初始化一个 bitset 数据结构的向量,比如b来存储顶点的所有支配者的集合。
- 对于每个节点i , b[i] 中的设置位将表示 i 的主要顶点集。
- 为了找到每个顶点的支配者,找到有向无环图中的所有路径很重要。
- 使用 DFS 遍历图形以查找图形中的所有路径。
- 从根节点即0开始遍历
- 在执行 DFS 时,对于每个顶点i
- 如果该节点尚未访问,则设置b[i] 的所有位并标记访问过的节点
- 将位集b[i]中的主导顶点集存储为其父节点的主导顶点集的交集。将b[i]更新为b[i] 和 b[parent] 。
- 更新 b[i][i] 的值变为1,因为每个节点都是自己的支配者。
- 递归地,为 i 的子节点调用 DFS 。
- 执行完上述步骤后,打印顶点的优势顶点,即b[i]中设置位的位置。
下面是上述方法的实现:
C++14
// C++ program for the above approach
#include
using namespace std;
// Declare bitsets for each
// vertex to store the set of
// dominant vertices
vector > b(100);
// Visited array to check if
// a vertex has been visited or not
int vis[100] = {};
// Function to find set of dominator
// vertices for a particular node
void findDominator(vector > graph,
bitset<100> par, int node)
{
// If node is unvisited
if (vis[node] == 0) {
// Set all bits of b[pos]
b[node] = ~b[node];
// Update vis[node] to 1
vis[node] = 1;
}
// Update b[node] with bitwise and
// of parent's dominant vertices
b[node] &= par;
// Node is itself is a
// dominant vertex of node
b[node][node] = 1;
// Traverse the neighbours of node
for (int i = 0; i < (int)graph[node].size(); i++) {
// Recursive function call to
// children nodes of node
findDominator(graph, b[node], graph[node][i]);
}
}
// Function to build the graph
void buildGraph(vector > adj, int E, int V)
{
// Vector of vector to store
// the adjancy matrix
vector > graph(V + 1);
// Build the adjacency matrix
for (int i = 0; i < E; i++) {
graph[adj[i].first].push_back(adj[i].second);
}
// Bitset for node 0
bitset<100> g;
// Node 0 itself is a dominant
// vertex of itself
g[0] = 1;
// Update visited of source
// node as true
vis[0] = 1;
// DFS from source vertex
findDominator(graph, g, 0);
}
// Function to find dominant set of vertices
void dominantVertices(int V, int E,
vector > adj)
{
// Function call to build the graph
// and dominant vertices
buildGraph(adj, E, V);
// Print set of dominating vertices
for (int i = 0; i < V; i++) {
cout << i << " -> ";
for (int j = 0; j < V; j++) {
if (b[i][j] == 1)
cout << j << " ";
}
cout << endl;
}
}
// Driver Code
int main()
{
// Given Input
int V = 5, E = 5;
vector > adj = {
{ 0, 1 }, { 0, 2 }, { 1, 3 }, { 2, 3 }, { 3, 4 }
};
// Function Call
dominantVertices(V, E, adj);
return 0;
}
0 -> 0
1 -> 0 1
2 -> 0 2
3 -> 0 3
4 -> 0 3 4
时间复杂度: O(V 3 )
辅助空间: O(V 2 )
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。