Gara delle mucche#10151

Gara delle mucche (Editoriale)

Dichiariamo una matrice booleana . Per ogni coppia di mucche e impostiamo g[a][b] = true, se la mucca vince contro la mucca . In questo modo, tracciamo un arco orientato da a . Poiché i risultati dei round sono coerenti, il grafo costruito è aciclico.

Il rango della mucca con numero può essere determinato se per ogni altra mucca è noto quale delle due sia più forte: o la mucca può battere la mucca (eventualmente attraverso diverse mucche intermedie), oppure la mucca può battere la mucca . In altre parole, nella chiusura transitiva del grafo, per ogni coppia e deve essere soddisfatta almeno una delle condizioni: g[i][j] = true oppure g[j][i] = true.

Allo stesso tempo, entrambi i valori g[i][j] e g[j][i] non possono essere uguali a , poiché ciò significherebbe la presenza di una contraddizione nei risultati delle gare.

Esempio

Nell'esempio riportato, è possibile determinare in modo univoco i ranghi solo per le mucche e .

La mucca vince contro la mucca , ma perde contro tutte le altre mucche. La mucca perde contro tutte le altre mucche.

Per la mucca non è noto se riuscirà a battere le mucche e . Analogamente, per le mucche e non è noto se riusciranno a battere la mucca . Pertanto, non è possibile determinare i ranghi esatti di queste mucche.

Implementazione dell'algoritmo

Dichiariamo una matrice booleana .

bool g[101][101];

Leggiamo i dati in input.

scanf("%d %d", &n, &m);

Consideriamo che ogni mucca vince contro sé stessa.

for (i = 1; i <= n; i++) g[i][i] = 1;

Leggiamo i dati in input. Costruiamo il grafo di input. Se la mucca ha vinto contro la mucca , tracciamo un arco da a .

for (i = 0; i < m; i++)
{
  scanf("%d %d", &a, &b);
  g[a][b] = 1;
}

Calcoliamo la chiusura transitiva del grafo. Se dal vertice al vertice esiste un percorso lungo gli archi del grafo, impostiamo g[i][j] = true.

for (k = 1; k <= n; k++)
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
  if (g[i][k] && g[k][j]) g[i][j] = true;

Nella variabile accumuliamo il numero di mucche per le quali è possibile determinare in modo univoco il rango.

res = 0;

In un ciclo, verifichiamo a turno ogni mucca e stabiliamo se sia possibile determinare in modo univoco il suo rango.

for (i = 1; i <= n; i++)
{

Verifichiamo se è possibile determinare il rango della mucca con numero . Per farlo, esaminiamo tutte le mucche . Se per una qualche mucca sono soddisfatte entrambe le condizioni: g[i][j] = false e g[j][i] = false, allora non è possibile stabilire quale delle due mucche sia più forte. Di conseguenza, non è possibile determinare il rango esatto della mucca con numero .

  bool good = true;
  for (j = 1; j <= n; j++)
    if (g[i][j] == false && g[j][i] == false)
    {
      good = false;
     break;
    }

Se dopo aver verificato tutte le mucche il valore di rimane uguale a , significa che per la mucca la sua posizione rispetto a ogni altra mucca è nota. Di conseguenza, il suo rango può essere determinato in modo univoco.

  if (good) res++;
}

Stampiamo la risposta.

printf("%d\n", res);