1 Отредактировано Roman Rubanenko (2009-12-19 13:08:04)

Тема: Поиск самых отдалённых вершин в дереве

Задано кол-во вершин в графе,потом N-1 строк по 3 числа(описание рёбер).
Требуется найти расстояние между двумя самыми отдалёнными вершинами в дереве.
Вот мой код,который не прходит все тесты из-за Time-limita в 2 секунды:

Var        root:array[0..1001] of longint;
           a,aa:array[0..1001,0..1001] of longint;
           b:array[0..1001] of boolean;
           d,i,j,n,m,z,x,y,num,u,max,min:longint;
  BEgin
    Assign(input,'input.txt');
    Reset(input);
    Read(n);
    for i:=1 to n do
      begin
        for j:=1 to n do
          a[i,j]:=0;
      end;
    for i:=1 to n-1 do
      begin
        Read(x,y,z);
       a[x,y]:=z;
        a[y,x]:=z;
        inc(root[x]);
        inc(root[y]);
      end;
      max:=0;
    for u:=1 to n do
      if root[u]=1 then begin
    d:=u;
    fillchar(b,sizeof(b),true);
      for i:=1 to n do
      begin
        num:=d;
        min:=maxlongint;
        for j:=1 to n do
          if (a[d,j]>0)and(b[j])and(a[d,j]<min) then begin
                                                       num:=j;
                                                       min:=a[d,j];
                                                     end;
        b[num]:=false;
        for j:=1 to n do
          if (a[num,j]>0)and((a[num,j]+a[d,num]<a[d,j])or(a[d,j]=0)) then a[d,j]:=a[d,num]+a[num,j];
      end;
    for i:=1 to n do
      if (a[d,i]>max)and(i<>d) then max:=a[d,i];
      end;
    Writeln(max);
    Close(input);
  End.

Я брал вершины  которые связаны лишь одним ребром с остальными и искал самые отдалённые вершины от них через алгоритм дейкстры.

2

Re: Поиск самых отдалённых вершин в дереве

Как я понял из вашего решения N = 1000 максимум.
Дальше вы написали Дейкстру за O(N^2). Максимальная сложность работы может составить O(N^3)! Что не уложится естественно по времени в 2 секунды.
Вам нужно либо написать Дейкстру с кучей за O(NlogN),тогда сложность программы составит O(N^2*logN),что улаживается  по врмени.
Но в данном случае у вас дано ДЕРЕВО,а это значит все пути в нём из одной вершины в другую однозначны,следовательно вам достаточно перебирать вершину с которой будут искаться расстояния,а потмо пускать либо Рекурсию,либо Очередь (DFS || BFS),так как пути однозначны,то в каждой вершине мы побываем 1 раз,и сложность программы составит O(N^2).

Re: Поиск самых отдалённых вершин в дереве

brainail пишет:

вам достаточно перебирать вершину с которой будут искаться расстояния,а потмо пускать либо Рекурсию,либо Очередь (DFS || BFS),так как пути однозначны,то в каждой вершине мы побываем 1 раз,и сложность программы составит O(N^2).

Re: Поиск самых отдалённых вершин в дереве

что значит "перебирать вершину"?и соответственно откуда пускать dfs/bfs?

5

Re: Поиск самых отдалённых вершин в дереве

Ну если вам не понятно тогда вот так:
Создадим матрицу Dij = расстояние между i-ой вершиной и j-ой.
Как её просчитать,для этого перебираем вершину i,теперь запускам очередь,или рекурсию что бы просчитать расстояния до всех остальных вершин с i-ой. Занесём все показатели в матрицу D.
Теперь когда у нас есть расстояния между всеми парами вершин,мы просто выбираем максимальное из всех таких расстояний,запоминая сами вершины.
Надеюсь так понятней.

6

Re: Поиск самых отдалённых вершин в дереве

опять
http://olympiads.ru/zaoch/2009/problems/l.shtml
? sad

7

Re: Поиск самых отдалённых вершин в дереве

При чём тут эта задача тут?

Re: Поиск самых отдалённых вершин в дереве

Уже была задача, сначала делаем обход из любой вершины, ищем самою дальнюю вершуну от начальной, из неё снова обход, который определит две самые удаленные вершины. сложность O(N)

9 Отредактировано Zayakin_Andrey (2009-12-20 20:24:49)

Re: Поиск самых отдалённых вершин в дереве

Уже была задача, сначала делаем обход из любой вершины, ищем самою дальнюю вершbну от начальной, из неё снова обход, который определит две самые удаленные вершины. сложность O(N)

10

Re: Поиск самых отдалённых вершин в дереве

Zayakin_Andrey пишет:

Уже была задача, сначала делаем обход из любой вершины, ищем самою дальнюю вершbну от начальной, из неё снова обход, который определит две самые удаленные вершины. сложность O(N)

Данное решение не будет работать на взвешенном дереве!
Оно будет работать если все рёбра по 1!
А что бы написать правильно то нужно писать как я сказал,
можно написать ещё быстрее чем я сказал,но думаю не нужно углубляться,
если и это вам не понятно,что достаточно при таком N,пустить с каждой вершины очередь или рекурсию и всё.

11

Re: Поиск самых отдалённых вершин в дереве

Можно довольно простой динамикой по дереву сделать за О(Н).
Выделим какую-то вершину как корень и топологически отсортируем дерево. Теперь пусть f(v) это максимальный путь в поддереве с корнем в вершине v, такой что оба его конца лежат в этом поддереве, а g(v) это максимальный путь в поддереве с корнем в v, такой что один его конец это лист этого поддерева, а второй - вершина v.
Тогда f(v)=max(f(v')) для всех потомков. Но считая его так мы не учтем, что может быть путь как бы "соединяется" в вершине v, поэтому в этот max следует еще включить 2 потомка v1 и v2, для которых g(v1)+edge(v,v1)+g(v2)+edge(v,v2) - максимально. Это легко сделать за О(количество потомков).
g(v)=max(g(v')+edge(v,v')) для всех потомков.
Тогда f(корень) и будет ответом.

12

Re: Поиск самых отдалённых вершин в дереве

brainail пишет:
Zayakin_Andrey пишет:

Уже была задача, сначала делаем обход из любой вершины, ищем самою дальнюю вершbну от начальной, из неё снова обход, который определит две самые удаленные вершины. сложность O(N)

Данное решение не будет работать на взвешенном дереве!
Оно будет работать если все рёбра по 1!
А что бы написать правильно то нужно писать как я сказал,
можно написать ещё быстрее чем я сказал,но думаю не нужно углубляться,
если и это вам не понятно,что достаточно при таком N,пустить с каждой вершины очередь или рекурсию и всё.

сори не заметил что граф взвешанный

Re: Поиск самых отдалённых вершин в дереве

1.Дфс только с одной вершины ничего не даст.
2.При N=1000 юзать дфс с каждой вершины ещё хуже чем Дейкстру.

14

Re: Поиск самых отдалённых вершин в дереве

KADR пишет:

Можно довольно простой динамикой по дереву сделать за О(Н).
Выделим какую-то вершину как корень и топологически отсортируем дерево. Теперь пусть f(v) это максимальный путь в поддереве с корнем в вершине v, такой что оба его конца лежат в этом поддереве, а g(v) это максимальный путь в поддереве с корнем в v, такой что один его конец это лист этого поддерева, а второй - вершина v.
Тогда f(v)=max(f(v')) для всех потомков. Но считая его так мы не учтем, что может быть путь как бы "соединяется" в вершине v, поэтому в этот max следует еще включить 2 потомка v1 и v2, для которых g(v1)+edge(v,v1)+g(v2)+edge(v,v2) - максимально. Это легко сделать за О(количество потомков).
g(v)=max(g(v')+edge(v,v')) для всех потомков.
Тогда f(корень) и будет ответом.

Я не спорю с тобой smile
Но ведь они не понимает ДВС или БФС со всех вершин,то и динамику не поймут я думаю.

15

Re: Поиск самых отдалённых вершин в дереве

brainail пишет:
KADR пишет:

Можно довольно простой динамикой по дереву сделать за О(Н).
Выделим какую-то вершину как корень и топологически отсортируем дерево. Теперь пусть f(v) это максимальный путь в поддереве с корнем в вершине v, такой что оба его конца лежат в этом поддереве, а g(v) это максимальный путь в поддереве с корнем в v, такой что один его конец это лист этого поддерева, а второй - вершина v.
Тогда f(v)=max(f(v')) для всех потомков. Но считая его так мы не учтем, что может быть путь как бы "соединяется" в вершине v, поэтому в этот max следует еще включить 2 потомка v1 и v2, для которых g(v1)+edge(v,v1)+g(v2)+edge(v,v2) - максимально. Это легко сделать за О(количество потомков).
g(v)=max(g(v')+edge(v,v')) для всех потомков.
Тогда f(корень) и будет ответом.

Я не спорю с тобой smile
Но ведь они не понимает ДВС или БФС со всех вершин,то и динамику не поймут я думаю.

Ну мне кажется, эта динамика проще чем дейкстра smile На самом деле все это делается в одном дфсе. Там выйдет строк 15-20, наверное.

16 Отредактировано brainail (2009-12-20 22:51:36)

Re: Поиск самых отдалённых вершин в дереве

Roman Rubanenko пишет:

1.Дфс только с одной вершины ничего не даст.
2.При N=1000 юзать дфс с каждой вершины ещё хуже чем Дейкстру.

А теперь посмотрим по чему Дейкстра в твоём решении хуже других алгоритмов!
1. Дейкстра обычно используется для разнообразных графов,а не отдельных видов,как в данном случае Дерево.
2. Так как у нас дерево то у нас все пути между двумя парами вершин однозначны,то есть не существует только один путь между всеми парами вершин,это кстати можно сказать и есть определение дерева.
3.Из пункта два следует,что нам не нужно между парами вершин выбирать какой-то наилучший путь,значит мы просто должны пройти по всем рёбрам лежащими между двумя парами вершин,это и будет длина пути между этими вершинами.
4.Твоя Дейкстра пускается с каждой вершины O(N),и работает она за O(N^2),и того общая сложность O(N^3).При N = 1000 это не успеет ~10^9.
5.Из пункта 2,3 следует что можно заменить Дейкстру любым алгоритмом поиска пути между двумя парами вершин,мы возьмём Очередь(BFS) или Поиск_в_Глубину(DFS). Оценим сложность: пробегаем по всем вершинам O(N),пускаем с каждой вершины (BFS or DFS) - O(N) (так как по каждому ребру мы пройдём один раз,больше нам не надо). И того O(N^2). При N = 1000 это спокойно успевает ~10^6.
6.В итоге получаем то же самое что и у тебя,только Дейкстру работающую за O(N^2) заменили на (BFS or DFS) работающих за O(N).
7.Пиши Дейкстру только на общих графах,которые не обладаю никакими свойствами.
8.Если ты понял что я написал выше,то можешь понять что написал "KADR" -> он привёл решение за O(N),которое оптимальное по времени,но немного сложнее для понимания.

17 Отредактировано amateur (2009-12-21 16:42:52)

Re: Поиск самых отдалённых вершин в дереве

Можно и так.
1) Запустить DFS из произвольной вершины. Каждый раз, посещая очередной лист, будем осуществлять перезапись расстояния и запоминать номер вершины, если нашли более длинный путь.
2) Запустить DFS из вершины, которую мы запомнили. Далее тоже самое(каждый раз, посещая очередной лист, будем осуществлять перезапись расстояния и запоминать номер вершины, если нашли более длинный путь).

18

Re: Поиск самых отдалённых вершин в дереве

Слушайте вы что сума сходите программисты, уже привели три решения, два из них очень простые, а одно из них оптимальное по скорости. Закрывайте топик! Хватит писать тут. А сам автор вопроса походу забил big_smile

19 Отредактировано 2rf (2009-12-21 18:25:36)

Re: Поиск самых отдалённых вершин в дереве

Интересно было бы посмотреть на контрпример к алгоритму, в к-ром ищем самую удаленную вершину от рандомной вершины, а потом самую удаленную от найденной.

20 Отредактировано chum (2009-12-21 21:48:00)

Re: Поиск самых отдалённых вершин в дереве

сколько раз берем рандомную вершину?)

21

Re: Поиск самых отдалённых вершин в дереве

Я только развеял свои сомнения smile Вообщем так,Roman Rubanenko -> тебе привели массу решений,выбирай,если что не понятно спрашивай.
2rf - ты прав,этот алгоритм тоже будет работать и на взвешенном графе,извините что сдуру ляпнул. Действительно взвешенное дерево это тоже не взвешенное просто каждое ребро с весом E,размножается на E подряд идущих рёбер,тем самым мы получим не взвешенное дерево,на котором будет работать данный алгоритм,значит он будет работать и на взвешенном дереве smile
Всё закрыли топик smile

22 Отредактировано KADR (2009-12-21 21:59:08)

Re: Поиск самых отдалённых вершин в дереве

chum пишет:

сколько раз берем рандомную вершину?)

Один. Если веса ребер положительные, то помоему, это даже правильно. Объяснить можно так: каждое ребро веса А представим в виде цепочки из А ребер веса 1. Тогда получим дерево, где все ребра веса 1, а на нем этот алгоритм правильный.

Edit: Beaten smile

23

Re: Поиск самых отдалённых вершин в дереве

KADR пишет:
chum пишет:

сколько раз берем рандомную вершину?)

Один. Если веса ребер положительные, то помоему, это даже правильно. Объяснить можно так: каждое ребро веса А представим в виде цепочки из А ребер веса 1. Тогда получим дерево, где все ребра веса 1, а на нем этот алгоритм правильный.

Edit: Beaten smile

ТЫ процетировал меня ! Я был раньше тебя smile

24

Re: Поиск самых отдалённых вершин в дереве

wink

25

Re: Поиск самых отдалённых вершин в дереве

ОК, убираем требование на :
1) целочисленность
2) положительность

весов ребер. Опять интересно посмотреть на контрпример.