Program Buses; Const MaxN=2000; MaxM=200000; Var N, M: LongInt; data: Array [1..MaxM, 1..2] of LongInt; index: Array [1..MaxN+1] of LongInt; neigh: Array [1..2*MaxM+2] of LongInt; setA, setB: Array [1..MaxN] of Boolean; // множества powerA, powerB: LongInt; // количество элементов в множестве deltaA, deltaB: Array [1..MaxN] of LongInt; // приращения nA, nB: LongInt; // размеры приращений f: Text; i, w, v, res: LongInt; Begin {INPUT} Assign(f, 'elect.in'); Reset(f); Readln(f, N, M); For i:= 1 To N Do Begin index[i]:= 0; setA[i]:= False; setB[i]:= False; End; For i:= 1 To M Do Begin Readln(f, data[i,1], data[i,2]); Inc(index[data[i,1]]); Inc(index[data[i,2]]); End; // сейчас index[i] - количество знакомых вершины i For i:= 2 To N+1 Do Begin Inc(index[i], index[i-1]); End; // а теперь index[i] - номер последней ячейки в отрезке знакомых вершины i For i:= 1 To M Do Begin neigh[index[data[i,1]]]:= data[i,2]; Dec(index[data[i,1]]); neigh[index[data[i,2]]]:= data[i,1]; Dec(index[data[i,2]]); End; For i:= 1 To N+1 Do Begin Inc(index[i]); End; // Сейчас index[i] стал номером ПЕРВОЙ ячейки в отрезке знакомых вершины i // Иначе говоря, в массиве data в ячейках от index[i] до (index[i+1] - 1) // хранится список номеров вершин соединённых с вершиной i {Первая рассылка} res:= 0; // res - это количество родственников Осла nA:= 0; For i:= 1 To N Do Begin Read(f, w); If w=1 Then Begin Inc(res); For w:= index[i] To index[i+1]-1 Do Begin v:= neigh[w]; If not setA[v] Then Begin setA[v]:= True; Inc(nA); deltaA[nA]:= v; End; End; End; End; // setA - это множество сторонников Осла после 1-й, 3-й, 5-й, ... рассылок // powerA - это количество элементов в setA { Легко понять, что все те, кто был готов голосовать за Осла после первой рассылки, будут готовы голосовать за него и после 3-ей рассылки, и после 5-ой и т.д. То есть множество setA не уменьшается, оно может только расширяться. Обозначим setA(k) множество setA после k-ой рассылки. Пусть delta = setA(3) - setA(1), т.е. setA(3) состоит из двух частей: setA(1) и delta. Рассмотрим setA(5). В него входят все знакомые людей из setA(3), т.е. setA(5) включает в себя всех тех, кто знаком с кем-нибудь из setA(1), а это в точности setA(3), плюс ещё, тех, кто знаком с кем-нибудь из delta. Иначе говоря, setA(5) можно построить так: к setA(3) добавить всех тех, кто не входит в setA(3), но имеет знакомых в delta. Понятно, что точно также можно построить setA(7), setA(9) и т.д. setA не может расширяться бесконечно долго - ведь у нас всего N людей. Значит, в какой-то момент setA не изменится, и после этого никаких изменений уже не будет } // deltaA - это множество людей, добавляемых на очередном шаге к setA // nA - это количество людей в нём // Совершенно аналогично, обозначим setB - множество сторонников // Осла после 2-й, 4-й, 6-й, ... рассылок // powerB - это количество элементов в setB // deltaB - это множество людей, добавляемых на очередном шаге к setB // nB - это количество людей в deltaB powerA:= nA; powerB:= 0; Close(f); Repeat {Пробегаемся по deltaA и вычисляем новые setB и deltaB } nB:= 0; For i:= 1 To nA Do Begin For w:= index[deltaA[i]] To index[deltaA[i]+1]-1 Do Begin v:= neigh[w]; If not setB[v] Then Begin setB[v]:= True; Inc(nB); deltaB[nB]:= v; End; End; End; Inc(powerB, nB); {Пробегаемся по deltaB и вычисляем новые setA и deltaA } nA:= 0; For i:= 1 To nB Do Begin For w:= index[deltaB[i]] To index[deltaB[i]+1]-1 Do Begin v:= neigh[w]; If not setA[v] Then Begin setA[v]:= True; Inc(nA); deltaA[nA]:= v; End; End; End; Inc(powerA, nA); Until nA=0; // Если deltaA пусто, то больше никаких добавлений не случится Assign(f, 'elect.out'); Rewrite(f); {Окончательный результат - это большее из трёх чисел: количество родственников Осла (т.е. тех, кто готов был голосовать за него с самого начала, и размеры множеств setA и setB } If powerA>res Then res:= powerA; If powerB>res Then res:= powerB; Writeln(f, res); Close(f); End.