draw attack graph tree software
Given an array arr[] of size N. There is an edge from i to arr[i]. The task is to convert this directed graph into tree by changing some of the edges. If for some i, arr[i] = i then i represents the root of the tree. In case of multiple answers print any of them.
Examples:
Input: arr[] = {6, 6, 0, 1, 4, 3, 3, 4, 0}
Output: {6, 6, 0, 1, 4, 3, 4, 4, 0}
Input: arr[] = {1, 2, 0};
Output: {0, 2, 0}.
Approach: Consider the 2nd example image above which shows an example of a functional graph. It consists of two cycles 1, 6, 3 and 4. Our goal is to make the graph consisting of exactly one cycle of exactly one vertex looped to itself.
Operation of change is equivalent to removing some outgoing edge and adding a new one, going to somewhat else vertex. Let's firstly make our graph containing only one cycle. To do so, one can choose any of initially presented cycles and say that it will be the only one. Then one should consider every other cycle, remove any of its in-cycle edges and replace it with an edge going to any of the chosen cycle's vertices. Thus the cycle will be broken and its vertices (along with tree ones) will be connected to the only chosen cycle. One will need to do exactly cycleCount – 1 such operations. Note that the removing of any non-cycle edge does not make sense, because it does not break any cycle.
The next thing is to make the cycle length be equal to 1. That might be already satisfied, if one will choose a cycle of minimal length and this length equals 1. Thus, if the initial graph contains any cycle of length 1, we are done with cycleCount – 1 operations. Otherwise, the cycle contains more than one vertex. It can be fixed with exactly one operation – one just needs to break any of in-cycle edges, say from u to arr[u], and add an edge from u to u. The graph will remain consisting of one cycle, but consisting of one self-looped vertex. In that case, we are done with cycleCount operations.
To do all the operations above, one can use DSU structure, or just a series of DFS. Note that there is no need in realisation of edge removing and creating, one just needs to analyze initial graph.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using
namespace
std;
int
find(
int
x,
int
a[],
int
vis[],
int
root[])
{
if
(vis[x])
return
root[x];
vis[x] = 1;
root[x] = x;
root[x] = find(a[x], a, vis, root);
return
root[x];
}
void
Graph_to_tree(
int
a[],
int
n)
{
int
vis[n] = { 0 }, root[n] = { 0 };
for
(
int
i = 0; i < n; i++)
find(a[i], a, vis, root);
int
par = -1;
for
(
int
i = 0; i < n; i++)
if
(i == a[i])
par = i;
if
(par == -1) {
for
(
int
i = 0; i < n; i++) {
if
(i == find(a[i], a, vis, root)) {
par = i;
a[i] = i;
break
;
}
}
}
for
(
int
i = 0; i < n; i++) {
if
(i == find(a[i], a, vis, root)) {
a[i] = par;
}
}
for
(
int
i = 0; i < n; i++)
cout << a[i] <<
" "
;
}
int
main()
{
int
a[] = { 6, 6, 0, 1, 4, 3, 3, 4, 0 };
int
n =
sizeof
(a) /
sizeof
(a[0]);
Graph_to_tree(a, n);
}
Java
import
java.util.*;
class
GFG
{
static
int
find(
int
x,
int
a[],
int
vis[],
int
root[])
{
if
(vis[x] ==
1
)
return
root[x];
vis[x] =
1
;
root[x] = x;
root[x] = find(a[x], a, vis, root);
return
root[x];
}
static
void
Graph_to_tree(
int
a[],
int
n)
{
int
[]vis =
new
int
[n];
int
[]root =
new
int
[n];
for
(
int
i =
0
; i < n; i++)
find(a[i], a, vis, root);
int
par = -
1
;
for
(
int
i =
0
; i < n; i++)
if
(i == a[i])
par = i;
if
(par == -
1
)
{
for
(
int
i =
0
; i < n; i++)
{
if
(i == find(a[i], a, vis, root))
{
par = i;
a[i] = i;
break
;
}
}
}
for
(
int
i =
0
; i < n; i++)
{
if
(i == find(a[i], a, vis, root))
{
a[i] = par;
}
}
for
(
int
i =
0
; i < n; i++)
System.out.print(a[i] +
" "
);
}
static
public
void
main ( String []arr)
{
int
a[] = {
6
,
6
,
0
,
1
,
4
,
3
,
3
,
4
,
0
};
int
n = a.length;
Graph_to_tree(a, n);
}
}
Python3
def
find(x, a, vis, root):
if
vis[x]:
return
root[x]
vis[x]
=
1
root[x]
=
x
root[x]
=
find(a[x], a, vis, root)
return
root[x]
def
Graph_To_Tree(a, n):
vis
=
[
0
]
*
n
root
=
[
0
]
*
n
for
i
in
range
(n):
find(a[i], a, vis, root)
par
=
-
1
for
i
in
range
(n):
if
i
=
=
a[i]:
par
=
i
if
par
=
=
-
1
:
for
i
in
range
(n):
if
i
=
=
find(a[i], a, vis, root):
par
=
i
a[i]
=
i
break
for
i
in
range
(n):
if
i
=
=
find(a[i], a, vis, root):
a[i]
=
par
for
i
in
range
(n):
print
(a[i], end
=
" "
)
if
__name__
=
=
"__main__"
:
a
=
[
6
,
6
,
0
,
1
,
4
,
3
,
3
,
4
,
0
]
n
=
len
(a)
Graph_To_Tree(a, n)
C#
using
System;
using
System.Collections.Generic;
class
GFG
{
static
int
find(
int
x,
int
[]a,
int
[]vis,
int
[]root)
{
if
(vis[x] == 1)
return
root[x];
vis[x] = 1;
root[x] = x;
root[x] = find(a[x], a, vis, root);
return
root[x];
}
static
void
Graph_to_tree(
int
[]a,
int
n)
{
int
[]vis =
new
int
[n];
int
[]root =
new
int
[n];
for
(
int
i = 0; i < n; i++)
find(a[i], a, vis, root);
int
par = -1;
for
(
int
i = 0; i < n; i++)
if
(i == a[i])
par = i;
if
(par == -1)
{
for
(
int
i = 0; i < n; i++)
{
if
(i == find(a[i], a, vis, root))
{
par = i;
a[i] = i;
break
;
}
}
}
for
(
int
i = 0; i < n; i++)
{
if
(i == find(a[i], a, vis, root))
{
a[i] = par;
}
}
for
(
int
i = 0; i < n; i++)
Console.Write(a[i] +
" "
);
}
static
public
void
Main ( String []arr)
{
int
[]a = { 6, 6, 0, 1, 4, 3, 3, 4, 0 };
int
n = a.Length;
Graph_to_tree(a, n);
}
}
Javascript
<script>
function
find(x, a, vis, root)
{
if
(vis[x] == 1)
return
root[x];
vis[x] = 1;
root[x] = x;
root[x] = find(a[x], a, vis, root);
return
root[x];
}
function
Graph_to_tree(a, n)
{
var
vis = Array(n).fill(0);
var
root = Array(n).fill(0);
for
(
var
i = 0; i < n; i++)
find(a[i], a, vis, root);
var
par = -1;
for
(
var
i = 0; i < n; i++)
if
(i == a[i])
par = i;
if
(par == -1)
{
for
(
var
i = 0; i < n; i++)
{
if
(i == find(a[i], a, vis, root))
{
par = i;
a[i] = i;
break
;
}
}
}
for
(
var
i = 0; i < n; i++)
{
if
(i == find(a[i], a, vis, root))
{
a[i] = par;
}
}
for
(
var
i = 0; i < n; i++)
document.write(a[i] +
" "
);
}
var
a = [6, 6, 0, 1, 4, 3, 3, 4, 0];
var
n = a.length;
Graph_to_tree(a, n);
</script>
Source: https://www.geeksforgeeks.org/convert-directed-graph-into-a-tree/
0 Response to "draw attack graph tree software"
Post a Comment