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);