Module: Padrões em Programação Dinâmica - 2


Problem

4 /5


Anão

Theory Click to read/hide

Isenção de responsabilidade: o método descrito abaixo não é universal, mas muitas vezes pode resolver um problema ou ajudá-lo a encontrar a solução certa.

Se você precisa verificar a existência de uma permutação em um problema, ou encontrar o número de permutações que correspondem, ou algo similar, então você deve considerar o uso da programação dinâmica de subconjuntos.

O parâmetro principal será uma máscara de bits, que mostrará quais elementos já foram incluídos na permutação e quais não foram. Muitas vezes também é necessário um segundo parâmetro que indica qual elemento foi incluído por último.

Freqüentemente, as permutações podem ser vistas no contexto de caminhos em gráficos. Assim, consideremos um exemplo clássico - o problema do caminho hamiltoniano.
Um caminho hamiltoniano é um caminho simples que passa por cada vértice do grafo exatamente uma vez. Pode ser representado simplesmente como uma permutação de comprimento n, onde n é o número de vértices. A ordem dentro desta permutação indicará a ordem na qual os vértices neste caminho são percorridos.

Para verificar a presença de um caminho hamiltoniano no grafo, vamos iniciar a dinâmica dp[mask][last] - existe um caminho simples que contornou os vértices marcados com uns no bitmask da máscara e acabou no último vértice.
Os valores iniciais serão dp[2i][i] = verdadeiro, o resto falso, o que significa que sempre há um caminho vazio começando em qualquer um dos vértices.
Tendo o valor true em dp[mask][last] faremos as transições para frente, no sentido de "estender o caminho". Ou seja, procuraremos o número de vértices marcados com zero na máscara (ainda não os visitamos no caminho) e ao mesmo tempo de forma que haja uma aresta do último a este vértice (o caminho deve ser estendido por uma aresta existente). Ou seja, fazemos dp[mask | 2k][k] = true if dp[mask][last] = true AND mask & 2k = 0 (o vértice k ainda não foi visitado) E há uma última aresta -> k.
Por fim, existe um caminho hamiltoniano se houver um valor verdadeiro em dp para os parâmetros da bitmask de todos os uns e qualquer último vértice.

Problem

Certa vez, o anão Quark encontrou um mapa do tesouro. Existem N pontos marcados no mapa onde o tesouro pode ser encontrado. Todos os pontos são numerados de 1 a N. Para cada par de pontos, o Quark sabe o comprimento da estrada que os conecta. Quark inicia sua busca no ponto número 1. Antes de iniciar sua longa jornada, o astuto anão risca pontos onde, em sua opinião, não pode haver tesouro. É garantido que o ponto número 1 nunca é riscado. Depois disso, o Quark escolhe alguma rota que passe por todos os pontos restantes do mapa. A rota não passa pelo mesmo ponto mais de uma vez. Um quark só pode andar em estradas que conectam pontos não cruzados.

Quark quer escolher uma rota de comprimento mínimo. É necessário encontrar tal rota para o Quark.

Entrada
A primeira linha contém um inteiro N (1 ≤ N ≤ 15) — o número de pontos marcados no mapa. As próximas N linhas contêm as distâncias entre os pontos. A (i+1)-ésima linha contém N inteiros di1,di2, diN — extensões de estradas do i-ésimo ponto a todos os outros. É garantido que dij=dji, dii=0 e 0 <dij < 100 . A (N+2)ª linha contém um inteiro Q (1 < Q ≤ 1000) — o número de opções para excluir pontos para este mapa. As linhas Q a seguir contêm uma descrição das opções de exclusão. A descrição começa com o número C (0 ≤ C < N) — o número de pontos onde, segundo Quark, o tesouro não pode estar. Os próximos C números fornecem os números desses pontos.

Impressão
Imprima linhas Q. Em cada linha, imprima um inteiro — o comprimento da rota mínima com a opção correspondente de exclusão de pontos.
Exemplos
# Entrada Saída
1 3
0  45 10
45 0  30
10 30 0
2
0
1 3
40
45
2 5
0  14 20 17 14
14 0  15 19 18
20 15 0  15 16
17 19 15 0  14
14 18 16 14 0
2
3 5 4 3
0
14
58