Оголосимо булеву матрицю . Для кожної пари корів і встановимо g[a][b] = true, якщо корова перемагає корову . Таким чином, проведемо орієнтоване ребро від до . Оскільки результати раундів несуперечливі, побудований граф є ациклічним.
Ранг корови з номером можна визначити, якщо для будь-якої іншої корови відомо, яка з них сильніша: або корова може перемогти корову (можливо, через кілька проміжних корів), або корова може перемогти корову . Іншими словами, у транзитивному замиканні графа для кожної пари і повинна виконуватися хоча б одна з умов: g[i][j] = true або g[j][i] = true.
Одночасно обидва значення g[i][j] і g[j][i] не можуть дорівнювати , оскільки це означало б наявність протиріччя в результатах змагань.
Приклад
У наведеному прикладі можна однозначно визначити ранги лише для корів і .
Корова перемагає корову , але програє всім іншим коровам. Корова програє всім іншим коровам.
Для корови невідомо, чи зможе вона перемогти корів і . Аналогічно, для корів і невідомо, чи зможуть вони перемогти корову . Тому точні ранги цих корів визначити неможливо.
Реалізація алгоритму
Оголосимо булеву матрицю .
bool g[101][101];Зчитуємо вхідні дані.
scanf("%d %d", Вважаємо, що кожна корова перемагає саму себе.
for (i = 1; i <= n; i++) g[i][i] = 1;Зчитуємо вхідні дані. Будуємо вхідний граф. Якщо корова перемогла корову , проводимо ребро від до .
for (i = 0; i < m; i++)
{
scanf("%d %d",
g[a][b] = 1;
}Обчислюємо транзитивне замикання графа. Якщо з вершини у вершину існує шлях по ребрах графа, встановлюємо 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] У змінній накопичуємо кількість корів, для яких можна однозначно визначити ранг.
res = 0;У циклі по черзі перевіряємо кожну корову і з'ясовуємо, чи можна однозначно визначити її ранг.
for (i = 1; i <= n; i++)
{Перевіримо, чи можна визначити ранг корови з номером . Для цього переберемо всіх корів . Якщо для якоїсь корови виконуються обидві умови: g[i][j] = false і g[j][i] = false, то неможливо визначити, яка з двох корів сильніша. Отже, точний ранг корови з номером визначити не можна.
bool good = true;
for (j = 1; j <= n; j++)
if (g[i][j] == false
{
good = false;
break;
}Якщо після перевірки всіх корів значення залишилося рівним , значить, для корови її положення відносно кожної іншої корови відоме. Отже, її ранг можна однозначно визначити.
if (good) res++;
}Виводимо відповідь.
printf("%d\n", res);