Je suis coincé dans un défi de code et je veux un indice .
PROBLÈME: Une structure de données arborescente (sans cycles) vous est demandée. Il vous est demandé de supprimer autant que possible les "arêtes" (connexions), créant ainsi des arbres plus petits avec un nombre pair de nœuds. Ce problème peut toujours être résolu car il existe un nombre pair de nœuds et de connexions.
Votre tâche consiste à compter les bords supprimés.
Entrée: La première ligne d'entrée contient deux entiers N et M. N est le nombre de sommets et M est le nombre d'arêtes. 2 <= N <= 100. Les M lignes suivantes contiennent deux entiers ui et vi qui spécifient un bord de l’arbre. (Index basé sur 1)
Résultat: Imprimez le nombre d'arêtes supprimées.
Exemple de saisie
10 9
2 1
3 1
4 3
5 2
6 1
7 2
8 6
9 8
10 8
Exemple de sortie: 2
Explication: En supprimant les arêtes (1, 3) et (1, 6), nous pouvons obtenir le résultat souhaité.
J'ai utilisé BFS pour parcourir les nœuds . Tout d'abord, maintenez un tableau séparément pour stocker le nombre total de nœuds enfants + 1 . Ainsi, vous pouvez attribuer initialement tous les nœuds feuilles de valeur 1 dans ce tableauMaintenant, commencez par le dernier nœud et comptez le nombre d'enfants pour chaque nœud. Cela fonctionnera de bas en haut et le tableau qui stocke le nombre de nœuds enfants facilitera l'optimisation du code au moment de l'exécution.
Une fois que vous obtenez le tableau après avoir obtenu le nombre de nœuds enfants pour tous les nœuds, il vous suffit de compter les nœuds avec un nombre pair de nœuds. Remarque: je n'ai pas inclus le nœud racine dans le décompte à l'étape finale.
Ceci est ma solution. Je n'ai pas utilisé d'arborescence bfs, mais juste un autre tableau pour contenir le nombre total de chaque nœud et de leurs nœuds enfants.
import Java.util.Scanner;
import Java.util.Arrays;
public class Solution {
public static void main(String[] args) {
int tree[];
int count[];
Scanner scan = new Scanner(System.in);
int N = scan.nextInt(); //points
int M = scan.nextInt();
tree = new int[N];
count = new int[N];
Arrays.fill(count, 1);
for(int i=0;i<M;i++)
{
int u1 = scan.nextInt();
int v1 = scan.nextInt();
tree[u1-1] = v1;
count[v1-1] += count[u1-1];
int root = tree[v1-1];
while(root!=0)
{
count[root-1] += count[u1-1];
root = tree[root-1];
}
}
System.out.println("");
int counter = -1;
for(int i=0;i<count.length;i++)
{
if(count[i]%2==0)
{
counter++;
}
}
System.out.println(counter);
}
}
Je sais qu'il a déjà été répondu à cette question ici, beaucoup de temps. Je veux toujours connaître les commentaires sur ma solution ici. J'ai essayé de construire le nombre d'enfants, car les contours passaient par l'entrée et tous les cas de test étaient réussis.
namespace Hackerrank
{
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
var tempArray = Console.ReadLine().Split(' ').Select(x => Convert.ToInt32(x)).ToList();
int verticeNumber = tempArray[0];
int edgeNumber = tempArray[1];
Dictionary<int, int> childCount = new Dictionary<int, int>();
Dictionary<int, int> parentDict = new Dictionary<int, int>();
for (int count = 0; count < edgeNumber; count++)
{
var nodes = Console.ReadLine().Split(' ').Select(x => Convert.ToInt32(x)).ToList();
var node1 = nodes[0];
var node2 = nodes[1];
if (childCount.ContainsKey(node2))
childCount[node2]++;
else childCount.Add(node2, 1);
var parent = node2;
while (parentDict.ContainsKey(parent))
{
var par = parentDict[parent];
childCount[par]++;
parent = par;
}
parentDict[node1] = node2;
}
Console.WriteLine(childCount.Count(x => x.Value % 2 == 1) - 1);
}
}
}
Si vous observez l'entrée, vous pouvez constater qu'il est assez facile de compter le nombre de nœuds situés sous chaque nœud. Considérez (a b) comme entrée Edge, dans tous les cas, a est l'enfant et b est le parent immédiat. L'entrée a toujours des arêtes représentées de bas en haut.
C'est donc essentiellement le nombre de nœuds qui ont un compte pair (à l'exclusion du nœud racine). J'ai soumis le code ci-dessous sur Hackerrank et tous les tests ont réussi. Je suppose que tous les cas de l’entrée satisfont à la règle.
def find_edges(count):
root = max(count)
count_even = 0
for cnt in count:
if cnt % 2 == 0:
count_even += 1
if root % 2 == 0:
count_even -= 1
return count_even
def count_nodes(Edge_list, n, m):
count = [1 for i in range(0, n)]
for i in range(m-1,-1,-1):
count[Edge_list[i][1]-1] += count[Edge_list[i][0]-1]
return find_edges(count)
Ma première tendance est de travailler à partir des nœuds d'extrémité, car vous ne pouvez pas couper leurs arêtes car cela laisserait des sous-arbres à un sommet.
Voici l'approche que j'ai utilisée pour réussir tous les tests.
Solution - Parcourez toutes les arêtes et comptez le nombre d'arêtes égales
Si nous supprimons un bord de l’arbre et qu’il en résulte deux arbres avec un nombre pair de sommets, appelons ce bord - même bord
Si nous supprimons un bord de l’arbre et qu’il en résulte deux arbres avec un nombre impair De sommets, appelons cela bord
Voici ma solution en rubis
num_vertices, num_edges = gets.chomp.split(' ').map { |e| e.to_i }
graph = Graph.new
(1..num_vertices).to_a.each do |vertex|
graph.add_node_by_val(vertex)
end
num_edges.times do |Edge|
first, second = gets.chomp.split(' ').map { |e| e.to_i }
graph.add_Edge_by_val(first, second, 0, false)
end
even_edges = 0
graph.edges.each do |Edge|
dup = graph.deep_dup
first_tree = nil
second_tree = nil
subject_Edge = nil
dup.edges.each do |e|
if e.first.value == Edge.first.value && e.second.value == Edge.second.value
subject_Edge = e
first_tree = e.first
second_tree = e.second
end
end
dup.remove_Edge(subject_Edge)
if first_tree.size.even? && second_tree.size.even?
even_edges += 1
end
end
puts even_edges
Note - Cliquez ici pour vérifier le code des classes Graph, Node et Edge
Voici les grandes lignes d'une approche alternative: