(Esto se deriva de un concurso de programación recientemente completado)¿Encontrando las "mejores raíces" en un gráfico de árbol dirigido?
Se le ha asignado G, un gráfico conectado con N nodos y N-1 bordes.
(Observe que esto implica G forma un árbol.)
Cada borde de G se dirige. (no necesariamente hacia arriba a cualquier raíz)
Para cada vértice v de G es posible invertir cero o más bordes de manera que haya una ruta dirigida desde cada vértice w a v. Deje el mínimo número posible de inversiones en los bordes para lograr esto, f (v).
¿Con qué algoritmo lineal o loglineal podemos determinar el subconjunto de vértices que tienen el mínimo global f (v) (incluido el valor de f (v) de esos vértices)?
Por ejemplo considerar el gráfico 4 vértice con estos bordes:
A<--B
C<--B
D<--B
El valor de f (A) = 2, f (B) = 3, f (C) = 2 y f (D) = 2 ...
..Así por lo tanto, la salida deseada es {a, C, D} y 2
(en cuenta que sólo necesitamos calcular el f (v) de vértices que tienen una f mínima (v) - no todos ellos)
Código:
Para la posteridad aquí está el código de la solución:
int main()
{
struct Edge
{
bool fwd;
int dest;
};
int n;
cin >> n;
vector<vector<Edge>> V(n+1);
rep(i, n-1)
{
int src, dest;
scanf("%d %d", &src, &dest);
V[src].push_back(Edge{true, dest});
V[dest].push_back(Edge{false, src});
}
vector<int> F(n+1, -1);
vector<bool> done(n+1, false);
vector<int> todo;
todo.push_back(1);
done[1] = true;
F[1] = 0;
while (!todo.empty())
{
int next = todo.back();
todo.pop_back();
for (Edge e : V[next])
{
if (done[e.dest])
continue;
if (!e.fwd)
F[1]++;
done[e.dest] = true;
todo.push_back(e.dest);
}
}
todo.push_back(1);
while (!todo.empty())
{
int next = todo.back();
todo.pop_back();
for (Edge e : V[next])
{
if (F[e.dest] != -1)
continue;
if (e.fwd)
F[e.dest] = F[next] + 1;
else
F[e.dest] = F[next] - 1;
todo.push_back(e.dest);
}
}
int minf = INT_MAX;
rep(i,1,n)
chmin(minf, F[i]);
cout << minf << endl;
rep(i,1,n)
if (F[i] == minf)
cout << i << " ";
cout << endl;
}
+1 - Encontré un contraejemplo para el mío y estoy bastante seguro de que este enfoque funciona. – dfb
me queda bien. Gracias. –
Un lema clave aquí es que para cualquier vértice v, existe exactamente un conjunto de inversiones de borde para crear una ruta desde todos los demás vértices hasta v. No lo noté cuando miré el problema originalmente. –