Искомый минимальный остов строится постепенно, добавлением в него рёбер по одному. Изначально остов полагается состоящим из единственной вершины (её можно выбрать произвольно). Затем выбирается ребро минимального веса, исходящее из этой вершины, и добавляется в минимальный остов.

С описания алгоритма Прима.
Я выбираю произвольно первую вершину, потом пробегаю её соседей, изменяю расстояние до них и на следующем проходе по циклу ищется минимальное среди путей из не добавленных вершин в множество добавленных, затем помечаю вершину куда идёт минимальное ребро (как бы добавляю ребро) и т.д.

Там в начале ищется минимум (он будет в вершине 1, там расстояние равно нулю) и если найдена не первая вершина, то кратчайшее расстояние добавляется в ответ.
На первом проходе не добавляется ребро "из никуда в v", там написан if.
d[ i] - текущее минимальное расстояние от первого ребра до i- ного.
Вроде так

V - это же номер вершины, он влезает.
Это дельфи, integer и longint одно и тоже

Попробовал с int64 - тоже самое.

Написал прогу, вычисляющую длину минимального остовного дерева по алгоритму Прима, успешно сдал на школе программиста (http://acmp.ru/index.asp?main=task&id_task=142). Но там ограничение по вершинам 100, по рёбрам 6000, по весу 30000 и не нужно проверять граф на связность. Мне же нужно сдать задачу с вершинами до 300, рёбрами до 50000, весом до 10000 и проверкой на связность. Вроде всё нормально, но выдаёт неправильный ответ на 2 тесте, не пойму почему!

const maxN=300;
var f,f1                    :text;
    d,from                  :array[1..maxN] of int64;
    mark                    :array[1..maxN] of boolean;
    a                       :array[1..maxN,1..maxN] of int64;
    n,m,s,k,min,r           :int64;
    i,u,v                   :integer;
 
 
begin
 reset(f,'spantree.in');
 rewrite(f1,'spantree.out');
 read(f,n,m);
 for i:=1 to n do
  for v:=1 to n do a[i,v]:=-1;{заполнение матрицы смежности}
 
 for i:=1 to m do begin
   read(f,u,v,s);
   a[u,v]:=s;
   a[v,u]:=s;
 end;{считана матрица}
 close(f);
 
 for i:=2 to n do d[i]:=high(int64);
 
 while k<n do begin
 
  min:=high(int64);
  for i:=1 to n do
   if (d[i]<=min) and (not mark[i]) then begin min:=d[i]; v:=i end;
   {нахождение минимального ребра из не U в U}
   if d[v]=high(int64) then begin write(f1,'-1'); close(f1); halt end;
   if v<>1 then r:=r+a[from[v],v];{добавление ребра в ответ и в множество U}
   mark[v]:=true;{помечаем v} inc(k);
   for i:=1 to n do
    if (not mark[i]) and (a[v,i]>-1) and (a[v,i]<d[i]) then begin
     d[i]:=a[v,i];
     from[i]:=v
    end;{пробегаем соседей v и изменяем кратчайший путь до них из U}
 
 end;
  write(f1,r);
  close(f1);
end.

      

31

(1 ответов, оставленных в Problems)

Дан неориентированный граф без кратных ребер и петель. Нужно расставить в вершинах числа так, чтобы если они соединены ребром то их НОД больше 1, а если не соединены то он=1 (взаимно простые). Подскажите алгоритм!

32

(7 ответов, оставленных в Problems)

KADR пишет:

Когда мы встречаем левую границу прямоугольника, увеличиваем в дереве отрезков значения на отрезке от нижнего до верхнего игрека на 1.

Можете пояснить, что значит "от нижнего до верхнего игрека". Т.е. мы встретили прямоугольник, смотрим какие у него координаты по игреку и в дереве отрезков увеличиваем значения у тех координат, что входят в данных прямоугольник?

33

(7 ответов, оставленных в Problems)

Извините, что такое заметание вертикальной прямой?

34

(7 ответов, оставленных в Problems)

Даны координаты левого верхнего и правого нижнего угла прямоугольного окна (координаты - целые числа, меньше 10^5 по модулю), их количество <=50000. Нужно найти точку, которая покрыта наибольшим числом окон, вывести искомое количество окон и координаты точки.

35

(1 ответов, оставленных в Problems)

Дан массив из N элементов и числа в нём целые от 1 до M (1<=N<=100000,1<=M<=100000). Массив - это типа кубики как они отражаются в зеркале, число M - число их цветов. Все имеющиеся кубики отражаются в зеркале а некоторые из "настоящих" кубиков тоже видны. Требуется найти количество "настоящих" кубиков (все возможные).
Например: дан массив 1 1 2 2 1 1. Может быть 3 кубика (1 1 2 - настоящие, 2 1 1 - отражение), 5 кубиков (1 - настоящий, 1 2 2 1 1 - отражение) и 6 кубиков - все отражены в зеркале.
Я решил эту задачу через хеши (вычисление хэшей всех префиксов и обратных префиксов), но видимо из-за большого M обрезание числа в int64 получается слишком большое и у меня выдаёт неправильный ответ.
Подскажите более подходящий алгоритм!