Вы работаете
менеджером в большой корпорации. Каждый работник может иметь несколько прямых
менеджеров и несколько непосредственных подчиненных. Его подчиненные, в свою
очередь, также могут иметь своих подчиненных. А его прямые менеджеры могут
иметь своих менеджеров. Будем говорить, что x является боссом y,
если существует такая последовательность работников a, b, …, d,
что x является менеджером a, a является менеджером b
и так далее, а d является менеджером y (если x является прямым
менеджером y, то x является боссом y). Если a
является боссом b, то b не может быть боссом a. Согласно
новой политике корпорации зарплата работника, не имеющего подчиненных, равна 1.
Иначе зарплата работника равна сумме зарплат всех его подчиненных.
Вам заданы
отношения между работниками. Необходимо найти зарплату всех работников.
Вход. Содержит несколько тестов. Первая
строка каждого теста содержит количество работников n (n ≤ 50). В
следующих n строках заданы отношения между работниками: j-ый
символ i-ой строки равен 'Y', если работник i является прямым
менеджером работника j, и 'N' иначе.
Выход. Для каждого теста вывести в отдельной строке
суммарную зарплату всех работников.
Пример входа |
Пример выхода |
1 N 4 NNYN NNYN NNNN NYYN 6 NNNNNN YNYNNY YNNNNY NNNNNN YNYNNN YNNYNN |
1 5 17 |
графы -
поиск в глубину
Совершим поиск в
глубину на ориентированном графе, заданного матрицей смежности. Функция dfs(i)
вычисляет зарплату i-го работника, и сохраняет ее в ячейке salary[i].
Сумма зарплат всех работников равна сумме элементов массива salary.
Пример
Графы, заданные
во втором и третьем тестах, изображены ниже. Возле каждой вершины записана
зарплата работника, ей соответствующая. Дуги дерева поиска в глубину изображены
красным цветом.
Матрицу
смежности графа храним в массиве rel.
Зарплату i-го работника подсчитываем в ячейке salary[i].
#define MAX 51
long long salary[50];
char
rel[MAX][MAX];
Функция dfs совершает поиск в глубину из вершины i – вычисление зарплаты i-го работника.
long long dfs(int i)
{
int j;
long long &res = salary[i];
Если зарплата i-го работника уже подсчитана
(salary[i] ≠ 0), то завершаем поиск.
if (salary[i]
> 0) return salary[i];
Иначе запускаем поиск в глубину со
всех сыновей вершины i, вычисляем зарплаты
всех подчиненных i-го работника. Зарплата i-го работника
равна сумме зарплат всех его подчиненных.
for(res = j =
0; j < n; j++)
if
(rel[i][j] == 'Y') res += dfs(j);
Если res = 0, то у i-го работника
нет подчиненных. Устанавливаем его зарплату равной 1.
if (res == 0)
res = 1;
return res;
}
Основная часть программы. Читаем в
массив rel матрицу смежности графа.
while(scanf("%d\n",&n) == 1)
{
for(i = 0; i
< n; i++) gets(rel[i]);
memset(salary,0,sizeof(salary));
Запускаем поиск в глубину на
ориентированном графе. Находим зарплату каждого работника.
for(i = 0; i
< n; i++)
if
(!salary[i]) dfs(i);
Вычисляем и выводим суммарную зарплату всех
работников res.
for(res = i =
0; i < n; i++)
res += salary[i];
printf("%lld\n",res);
}
Java реализация
import java.util.*;
import java.io.*;
public class Main
{
static String rel[];
static long salary[];
public static long dfs(int i)
{
int j;
if (salary[i] > 0) return salary[i];
for(j = 0; j < rel.length; j++)
if (rel[i].charAt(j) == 'Y') salary[i] += dfs(j);
if (salary[i] == 0) salary[i] = 1;
return salary[i];
}
public static void main(String[] args) throws IOException
{
//Scanner con = new Scanner(new
FileReader ("4077.in"));
Scanner con = new Scanner(System.in);
while(con.hasNext())
{
int n = con.nextInt();
rel = new String[n];
for(int i = 0; i < n; i++)
rel[i] = con.next();
long res = 0;
salary = new long[n];
for(int i = 0; i < n; i++)
if (salary[i] == 0) dfs(i);
for(int i = 0; i < n; i++)
res += salary[i];
System.out.println(res);
}
con.close();
}
}