infoarena

infoarena - concursuri, probleme, evaluator, articole => Arhiva educationala => Subiect creat de: Filip Cristian Buruiana din Februarie 27, 2008, 23:01:42



Titlul: 009 Algoritmul lui Dijkstra
Scris de: Filip Cristian Buruiana din Februarie 27, 2008, 23:01:42
Aici puteţi discuta despre problema Algoritmul lui Dijkstra (http://infoarena.ro/problema/dijkstra).


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Alina Ene din Februarie 27, 2008, 23:39:26
O varianta dragutza a algoritmului lui Dijkstra foloseste "buckets" in loc de heaps si merge foarte bine in practica. Nu imi amintesc exact daca are un nume, cred ca e cunoscut ca Dial's implementation of Dijkstra's algorithm. Algoritmul e foarte simplu si foloseste cateva idei dragutze care s-ar putea sa fie utile.

Pot sa schitzez algoritmul daca starneste interesul cuiva :).

Later edit:

Dial's algorithm - varianta naiva:

Algoritmul lui Dial difera de algoritmul lui Dijkstra prin metoda in care selecteaza nodul cu distantza temporara minima la fiecare pas. Fie C lungimea maxima a unei muchii in G. Algoritmul mentine nC + 1 buckets numerotate de la 0 la nC: in bucket k se afla toate nodurile cu distantza temporara egala cu k (orice distantza temporara finita este cel mult nC). 

Pentru a selecta nodul cu distantza temporara minima, scanam buckets 0, 1, ... pana intalnim primul bucket k care nu e gol (fiecare nod din bucket k este un nod cu distanza temporara minima). Pentru fiecare nod v din bucket k, stergem v din bucket, marcam distantza lui v ca permanenta si modificam distantele vecinilor lui v (daca e necesar). Cand distantza unui nod v este schimbata de la d_1 la d_2, mutam v din bucket d_1 in bucket d_2 (daca d_1 este infinit, v intra in bucket d_2). La urmatorul pas, vom rezuma scanarea incepand de la bucket k + 1. Algoritmul merge pentru ca distantzele marcate ca permanente in algoritmul lui Dijkstra sunt non-decreasing. Buckets pot fi implementate folosind liste dublu inlantuite (ca sa obtinem O(1) pentru fiecare operatie necesara: verifica daca un bucket e gol, sterge un element din bucket, adauga un element in bucket).

Worst-case running time e O(m + nC) care e nu e polinomial, dar algoritmul e foarte rapid in practica.  Spatiul necesar e O(nC), dar se poate mult mai bine. E suficient sa mentinem doar C + 1 buckets. Buckets sunt numerotate de la 0 la C si un nod v cu distantza finita d(v) este in bucket d(v) mod(C + 1). Aceasta varianta se bazeaza pe urmatoarea observatie: daca un nod u a primit o distantza permanenta la inceputul unei iteratii a algoritmului lui Dijkstra, toate nodurile v cu distantza temporara finita satisfac d(v) <= d(u) + C la sfarsitul iteratiei. Asa ca in orice moment un anumit bucket contine doar noduri cu aceeasi distantza (in plus, daca un nod cu distantza minima e in bucket k, buckets k + 1, k + 2,  ..., C, 0, 1, ..., k - 1 contin noduri cu distantza din ce in ce mai mare).

Mai sunt doua idei dragutze (Dial's implementation cu "bounded-width buckets" si "multi-level buckets") pe care poate o sa le scriu in curand.

Se pare ca ia 100 (cam la limita pe ultimul test) (http://infoarena.ro/job_detail/144869)

Un mic articol despre Dial's algorithm and variations o sa apara aici: http://infoarena.ro/dijkstra-buckets
 


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Andrei Grigorean din Februarie 28, 2008, 00:42:23
Posteaza-l te rog. M-ai facut curios.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Cosmin Negruseri din Februarie 28, 2008, 01:50:43
wefgef: nu mai stii problema car? exact chestia asta faci: tii liste pentru costuri fixate.

La asta ma refeream cand am pus in training-path (http://infoarena.ro/training-path) dijkstra cu costuri mici.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Alina Ene din Februarie 28, 2008, 02:31:40
Era postat pe site deja? Oops, ar trebui sa ma uit mai atent in viitor  :-' .


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Cosmin Negruseri din Februarie 28, 2008, 03:08:40
E doar o solutie a unei probleme din concurs unde costurile sunt 0, 1, 2, 3, nu o explicatie detaliata a algoritmului general.

Uite un articol in ginfo despre acelasi algoritm: http://www.ginfo.ro/revista/13_6/focus2.pdf


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Andrei Grigorean din Februarie 28, 2008, 09:06:52
wefgef: nu mai stii problema car? exact chestia asta faci: tii liste pentru costuri fixate.

La asta ma refeream cand am pus in training-path (http://infoarena.ro/training-path) dijkstra cu costuri mici.

Nu stiam ca asta e numele algoritmului :).


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Cosmin Negruseri din Februarie 28, 2008, 09:41:49
@byndsr poti baga descrierea ce ai facut-o in un articol scurt si cu link spre problema asta si implementarea ta si spre problema car. Infoarena e wiki deci poti sa contribui usor si algoritmul e misto sa fie mentionat.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Stefan-Alexandru Filip din Martie 01, 2008, 10:20:42
O alta implementare care ia 100 de puncte este folosind priority_queue din STL. Daca imi amintesc bine, Cosmin ii spunea lazy detection.
La problema asta am observat din nou, cat de rapide sunt streamurile din g++ 4.2. Folosind functiile standard iau 90 de puncte, pentru ca ultimul test iese din timp. Folosind insa streamurile, ultimul test intra in aprox 450 ms.

Nu stiu ce nume are. Bellman-Ford cu coada, din cate stiu se numeste Bellman-Kalaba. Poate are si el un nume de care nu am auzit inca. Nu auzisem nici numele de Dial, desi am folosit in mai multe probleme BFS/Bellman-Ford cu cozi pentru fiecare cost.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Mircea Dima din Martie 01, 2008, 10:23:46
Eu as spune ca e un Bellman-Ford cu priority_queue :-"... e exact ca bellman-ford cu coada numai ca in loc de coada e folosit un heap


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Bogdan-Cristian Tataroiu din Martie 01, 2008, 10:30:09
Pai atunci Dijkstra in sine e Bellman-Ford cu Set / Heap... Dijkstra se bazeaza pe ideea de a extrage minimul la fiecare pas si a scoate nodul acela din graf... Bellman-Ford cu sau fara coada se bazeaza pe faptul ca dupa N relaxari a tuturor muchiilor distantele minime sunt calculate...


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Ionita Alexandru din Martie 05, 2008, 21:40:22
o alta varianta de implementare: in loc de heap folosim un arbore de intervale. mi se pare putin mai scurta implementarea.


Titlul: Questions from a newbie
Scris de: Bula Ionut din Martie 10, 2008, 17:37:29
 ce face un heap in algoritmul lui dijkstra? e o coada cu prioritate? apropo credeti ca e mai bun un heapsort decat un quicksort?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Filip Cristian Buruiana din Martie 10, 2008, 17:43:52
Algoritmul lui Dijkstra alege la fiecare pas nodul inca neales de cost minim. Daca tu mentii un vector, va trebui de fiecare data sa parcurgi tot vectorul pentru a vedea care este acest nod, si asta se poate dovedi ineficient. Daca vrei sa faci mai bine, trebuie sa gasesti o structura de date care sa poata extrage minimul si modifica valoarea unui element/sterge un element in O(1) sau O(logN). Aceasta structura poate fi un heap.
Astfel, cand aplici algoritmul lui dijkstra, ca sa afli care este nodul de cost minim inca neales interoghezi heapul in complexitate O(1). Ai aflat acest nod si il stergi din heap, cu complexitate O(logN). Apoi relaxezi toate muchiile din nodul curent, care inseamna sa modifici valoarea costului unui nod in heap, care se realizeaza tot cu complexitate O(logN).
Complexitatea finala va fi O(M log N), care, daca graful este rar, este mult mai buna decat O(N^2).


Titlul: Răspuns: Questions from a newbie
Scris de: Andrei Grigorean din Martie 10, 2008, 17:46:44
ce face un heap in algoritmul lui dijkstra? e o coada cu prioritate? apropo credeti ca e mai bun un heapsort decat un quicksort?

Un heap este intr-adevar o coada de prioritate.

Quicksort e mai bun decat heapsort si e si mai scurta implementarea.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Ciocas Radu din Martie 10, 2008, 18:19:30
cred ca s-au reavaluat sursele aveam 100 si acum vad ca am 90, oricum m-am chinuit si prima oara sa obtin 100, acuma nu am idei inafara faptul ca eu cred ca folosesc prea mult memorie fapt ce imi incetineste executia.
am declarat :
Cod:
 const
pinfinit=maxlongint;
type long=1..50000;
     pnod=^nod;
     nod=record
         nod:long;
         i:0..1000;
         urm:pnod;
         end;
     cheie=record
           val:longint;
           poz:long;
           end;
     vec=array[1..50000]of long;
var a:array[1..50000]of pnod;
    d:array[1..50000]of record
                        d:longint;
                        s:0..1;
                        end;
    id:^vec;
    h:array[1..50000]of cheie;
    i,poz,n,m,dheap,he,min:longint;
    p:pnod;
    ok:boolean;
    g:text;
 

 A - lista muchiilor
 D- distanta minima pana la fiecare nod si un alt camp care retine daca nodul mai este sau nu in coada ( initial aveam 2 vectori distincti dar am constatat cu uimire ca daca declar un singur vector de inregistrari cu 2 campuri, programul ruleaza mai repede desi nu inteleg de ce)
 H - heapul
 ID - vector auxiliar pt operatiile in heap
Cu ce ma complic ca nu imi dau seama ? (ies din timp la ultimul test)


Titlul: Răspuns: Questions from a newbie
Scris de: Mircea Pasoi din Martie 10, 2008, 18:53:49
ce face un heap in algoritmul lui dijkstra? e o coada cu prioritate? apropo credeti ca e mai bun un heapsort decat un quicksort?

Un heap este intr-adevar o coada de prioritate.

Quicksort e mai bun decat heapsort si e si mai scurta implementarea.

Un heap nu este o coada de prioritate. Poti implementa o coada de prioritate folosind un heap, dar o coada de prioritate este o structura de date abstracta (http://en.wikipedia.org/wiki/Abstract_data_type).


Titlul: more questions from a newbie
Scris de: Bula Ionut din Martie 11, 2008, 14:59:13
dijkstra cu heap e mai bun intr-un graf cu costuri pozitive,decat bellman ford cu coada?
 iar oftopic, pentru arborele partial de cost minim, algoritmul lui prim este mai eficient decat altii?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Andrei Grigorean din Martie 11, 2008, 15:06:13
Dijkstra cu heapuri are complexitatea mai buna, deci ar trebui sa fie mai rapid, insa bellman ford se implementeaza mai rapid :).

Pentru APM, eu folosesc Kruskal, tot datorita implementarii mult mai simple. Teoretic, Prim este mai bun.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Bula Ionut din Martie 11, 2008, 17:32:02
OK mersi


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Cosmin Negruseri din Martie 17, 2008, 22:21:06
Kruskal e O(m log m + m log* n) daca folosesti structuri de multimi disjuncte. Daca il implementezi tzaraneste are O(m log m + n^2).

Algoritmul lui Prim daca il implementezi ca in manual are complexitate O(n^3), daca il implementezi dupa cum se sugereaza in cormen ajungi la O(n^2) sau O(m log n) daca folosesti heapuri.

Se merita sa folosesti Prim in loc de Kruskal cand graful e dens. Eu am primit la o finala agora o problema unde trebuia sa determini arborele partial de cost minim pentru un graf dat de niste puncte in plan. In cazul asta algoritmul lui Prim are complexitate O(n^2) pe cand cel a lui Kruskal are O(n^2 log n), si asta era diferenta intre 100 si 40 de puncte.

Pentru curiosi, arborele partial de cost minm intr-un graf de genul asta se poate determina in complexitate O(n) dar acest rezultat este unul teoretic. Alta observatie misto este ca muchiile din arborele partial de cost minim in graful de care am vorbit apartin triangularizarii Delaunay care se poate determina in timp O(n log n) si are cel mult 3n - 6 muchii.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Andrei Grigorean din Martie 18, 2008, 11:24:20
http://en.wikipedia.org/wiki/Euclidean_minimum_spanning_tree

S-a gasit O(N)?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Cosmin Negruseri din Martie 18, 2008, 18:46:12
Vorbeam prostii, dar exista un algoritm randomizat ce gaseste arborele partial de cost minim al unui graf in O(m). Pentru grafuri planare intr-adevar algoritmul e O(n log n).


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Alina Ene din Martie 18, 2008, 19:46:34
Pentru grafuri planare, cel mai bun algoritm deterministic e O(n) (Cheriton-Tarjan). Pentru grafuri generale, cel mai bun algoritm deterministic e O(m alpha(n, m)) (alpha -- inverse Ackerman function) (Chazelle).


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Pripoae Teodor Anton din Aprilie 07, 2008, 19:11:52
eu cu Bellman Ford iau doar 40 (3 TLE si 3 SIGSEGV) se poate implementa BF pt 100 ?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Andrei Grigorean din Aprilie 07, 2008, 19:16:50
Se poate: http://infoarena.ro/job_detail/154087?action=view-source


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Pripoae Teodor Anton din Aprilie 07, 2008, 19:22:07
e BF cu heapuri?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Bogdan-Cristian Tataroiu din Aprilie 07, 2008, 19:27:49
vectorii cu "heap" nu sunt folositi si probabil au ramas de la sursa in care a facut dijkstra


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Pripoae Teodor Anton din Aprilie 22, 2008, 21:04:14
am implementat cu Bellman-Ford cu coada dar iau doar 30 (ok pe 1 2 si 8 , 5 wa si 2 TLE <astea se rezolva cu parsarea citirii>) si nu-mi dau seama unde crapa... ma poate ajuta cineva?

http://infoarena.ro/job_detail/183901?action=view-source (http://infoarena.ro/job_detail/183901?action=view-source)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Lucian Boca din Aprilie 22, 2008, 21:13:08
In principiu, bagi un nod in coada numai daca nu este deja acolo. Vad ca tu bagi un nod in coada la fiecare relaxare.
Nu stiu daca WA e de la asta, dar.. pune si conditia asta prin sursa ;)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Pripoae Teodor Anton din Aprilie 23, 2008, 09:02:52
Nup nu e de la asta. cu chestia ta iau doar 10 puncte pe testul 8. Eu bag un nod in coada de mai multe ori doar daca costul obtinut pana atunci este mai mic decat costul obtinut mai devreme, si atunci trebuie sa reactualizez si toti vecinii lui.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Andrei Grigorean din Aprilie 23, 2008, 10:32:44
Pai nu trebuie sa bagi un nod in coada decat daca nu este deja acolo.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Lucian Boca din Aprilie 23, 2008, 10:42:05
M-am uitat inca o data peste sursa ta si am vazut ca tu tii o coada de structuri cu nodul si distanta pana la el. Am impresia ca aici complici lucrurile; eu propun urmatoarea varianta: tii un vector dist[ x ] in care retii distanta minima (pana in prezent) pana la nodul x, iar in coada bagi numai indicii nodurilor, nu si distantele. Din nou, bagi un nod in coada numai daca nu este deja acolo.

Asadar, transformarile intr-un pseudo-C :D ar arata cam asa:
Cod:
coada.push( 1 );
incoada[1] = 1;

while( !coada.empty() ) {
u = coada.pop(), incoada[u] = 0;
for( v vecin al lui u )
if( dist[v] > dist[u] + cost(u,v) ) {
dist[v] = dist[u] + cost(u,v);
if( incoada[v] == 0 )
incoada[v] = 1, coada.push(v);
}
}


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Andrei Grigorean din Aprilie 23, 2008, 11:26:34
Am scris acum o sursa cu bellman-ford (http://infoarena.ro/job_detail/184224?action=view-source). Poti sa te uiti peste ea daca vrei.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Lucian Boca din Aprilie 23, 2008, 11:36:36
 :o Sunt mai rapide streamurile decat ma asteptam... Eu am luat mai demult, pe aceeasi idee (http://infoarena.ro/job_detail/156805?action=view-source), 90 cu citire standard. La ONI se va folosi tot g++ 4.2?

LE: Nop, citat de pe site-ul oficial:
Citat
5. Linux    g++ 3.2.2    compilator pentru limbajul C++


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Pripoae Teodor Anton din Aprilie 23, 2008, 12:57:56
@wefgef
nu prea stiu c++ si chestii cu push si iteratori

@amadaeus

dap. asta pt ca se foloseste evalul . campion care merge doar pe gcc vers 3. :(


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Andrei Grigorean din Aprilie 23, 2008, 13:05:10
Pai de ce nu inveti? Crezi ca e asa mare filozofie? :)

Exact, ce anume nu intelegi din sursa mea? :P


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Pripoae Teodor Anton din Aprilie 23, 2008, 13:11:29
cum e cu iteratorii


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Lucian Boca din Aprilie 23, 2008, 13:28:06
Iteratorii sunt un fel de pointeri, cu care poti parcurge un container (de exemplu un vector).
Iti recomand cartea "STL Tutorial and Reference Guide", de Musser, Derge si Saini - dupa bucata introductiva iti vei forma o parere destul de clara asupra STL-ului, iar acesta va fi un pas mare inainte ;)

Daca nu gasesti in alta parte, am uploadat-o aici (http://www.amadaeus.as.ro/C++%20STL%20Programming%20with%20the%20Standard%20Template%20Library,%20Tutorial%20and%20Reference%20Guide%201996.pdf).


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Andrei Grigorean din Aprilie 23, 2008, 14:23:21
 =D&gt; amadaeus.

Ceea ce fac eu acolo cu iteratorul este parcurgerea listei de vecini. As fi putut sa fac asa:

Cod:
for (int i = 0; i < int(G[nod].size()); ++i)

iar in loc de it->first as fi avut G[nod][ i ].first si in loc de it->second as fi avut G[nod][ i ].second.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Pripoae Teodor Anton din Aprilie 25, 2008, 18:10:29
Am reusit in sfarsit sa iau 100 dar cu citire cu streamuri ( cu citire in c imi crapa)... si testele par ciudate: imi crapa mozilla cand intru in ele

LE: gata... am scos 100 si cu citire in c (si 428 de ms pe cel mai mare test) cu bellman ford cu coada

http://infoarena.ro/job_detail/185953 (http://infoarena.ro/job_detail/185953)

si se pare ca sunt singurul cu c care a luat 100


deci se poate si in c

[editat de moderator: nu posta de mai multe ori consecutiv, foloseste edit]


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Lucian Boca din Aprilie 26, 2008, 14:56:06
Daca parsezi citirea, se poate in C si cu Dijkstra cu heapuri (http://infoarena.ro/job_detail/186013 (http://infoarena.ro/job_detail/186013))


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Pripoae Teodor Anton din Aprilie 26, 2008, 15:04:07
dap. si e chiar mai rapid cu heapuri. Dar eram primul care a luat 100 in c

http://infoarena.ro/monitor?task=dijkstra&&compiler=c&&score_begin=100 (http://infoarena.ro/monitor?task=dijkstra&&compiler=c&&score_begin=100)

aici apar toti cu 100 in c pe dijkstra


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Bogdan-Cristian Tataroiu din Aprilie 26, 2008, 15:31:23
oricum probabil exista destule surse trimise cu cpp care ar compila in c si ar lua 100  :-s


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Cosmin Negruseri din Mai 27, 2008, 07:11:07
@Airinei

Auzi, ma uitam la sursa ta ce e linkata din problema si vad ca folosesti set cand puteai folosi priority queue fara nici o problema. Nu folosesti nimic din avantajele setului aici ...

Si inca o chestie, cred ca faci chestii redundante pentru ca nu faci lazy deletion. Inainte de a folosi o valoare din heap poti sa testezi daca valoarea ce o folosesti in relaxari. Trebuie sa testezi if (val > d[ x ]) continue;


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Pripoae Teodor Anton din Iunie 02, 2008, 08:43:46
am trimis de mai multe ori aceeasi sursa, a doua oara cu niste comentarii in ea,

http://infoarena.ro/job_detail/193067
http://infoarena.ro/job_detail/193068

si obtin timpi foarte diferiti... gen 500 si 472. stiam ca de obicei timpul poate varia cu cel mult 8 ms dar poate chiar asa de mult? Adica 30 de ms? Poate fi de la alocarea dinamica a memoriei?

Need help...


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Stefan Istrate din Iunie 02, 2008, 13:44:42
E nesemnificativa diferenta ;) La problemele cu limite mari de timp (3-5 secunde) mi s-a intamplat sa am diferente pe aceeasi sursa de 50-100 ms.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Bivol Mihai din Februarie 09, 2009, 18:20:48
am incercat cu bf cu coada si vad ca primesc tle desi sunt sub 0.5 sec  :?

 10   472ms   4792kb   Time limit exceeded.   0

sau

 10   488ms   4788kb   Time limit exceeded.   0

in timp ce pe sursa lui wefgef

 10   488ms   4564kb   OK   10
 


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Sima Cotizo din Februarie 09, 2009, 18:38:59
Evaluatorul are o mica eroare in masurarea timpilor de executie afisati, dar fii sigur ca algoritmul tau este oprit atunci cand depaseste timpul.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Emanuel Cinca din Februarie 26, 2009, 18:26:07
poate cineva sa arunce o privire aici si sa-mi spuna unde e greseala... am incercat in nu mai stiu cate feluri si tot nu reusesc sa gasesc ce nu e in regula... mersi! :)

http://infoarena.ro/job_detail/267069

LE: am marit coada si intra pe 9 teste... pe al 10-lea iau TLE... o sa implementez coada dinamic si atunci sper sa intre... are totusi cineva vreun pont cum sa nu bag de mai multe ori acelasi nod in coada, in afara de STL?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Florian Marcu din Februarie 26, 2009, 21:20:19
Parseaza citirea. Si eventual foloseste un viz[] ca aici (http://infoarena.ro/job_detail/209298?action=view-source).Succes!


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Flaviu Pepelea din Februarie 26, 2009, 22:59:25
Are si el vectorul viz in program cu aceasi semnificatie. Insa, el adauga tot la sfarsit noduri, iar astfel exista riscul de a ii iesi din limitele cozii. Alternative ar fi: sa adaugi intodeauna un nod pe pozitia (poz_ult_nod_din_lista + 1) % N, unde N este numarul de noduri, sa incerci sa folosesti coada din stl sau sa implementezi o coada dinamica. :D


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Emanuel Cinca din Februarie 26, 2009, 23:42:17
am implementat o coada dinamica, am probleme doar cu timpul la ultimul test... am incercat si varianta lui Florian, mai putin parsarea citirii... deci probabil de acolo se trage TLE-ul... am incercat si citire in C si streamuri... acelasi rezultat... acum e prea tarziu sa mai incerc coada din STL, poate maine... multumesc oricum de raspunsuri! :ok:


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: razyelx din Martie 03, 2009, 22:47:09
Imi poate explica si mie cineva de ce Dijkstra nu merge pe costuri negative, va rog. Eu l-am implementat si am pus doua muchii negative si mi-a mers de minune. Deci cum e cu asta?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Andrei Grigorean din Martie 03, 2009, 22:57:22
Se da urmatorul graf orientat:
Cod:
4 4
1 2 5
1 3 10
3 2 -7
2 4 5

Iti da bine?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Tandrau Alexandru din Martie 03, 2009, 22:58:49
Pe scurt, muchiile negative nu merg cu Dijkstra deoarece in momentul in care scoti un nod din heap (nodul cu cel mai mic cost) tu il consideri terminat (cost optim in el). Sa-ti dau un exemplu. Sa presupunem ca ai muchia de la 2 la 1 cu costul -5. In Dijkstra ai ajuns sa ai d[1] = 4 si d[2] = 5. Nodul cu cel mai mic cost e 1, deci il scoti din heap si ai terminat socoteala cu el. Insa exista un cost mai bun pe care nu l-ai luat in calcul, si anume drumul care ajunge in nodul 2 cu costul 5, si apoi ia muchia de la 2 la 1, ajungand in 1 cu costul 0.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: razyelx din Martie 03, 2009, 23:54:01
Ms fain. Acum am inteles si eu care e treaba. Daca exista costuri negative, atunci se poate intampla ca drumul de la un nod i la un nod j sa scada(prin adunare cu o valoare negativa), iar daca nodul j a fost selectat in trecut atunci drumurile care au trecut de la i prin j, nu vor fi actualizate cu noua valoare. Mda.. inca o data ms fain.  :ok:


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Philip din Martie 09, 2009, 09:42:09
Cum de reuseste sursa http://infoarena.ro/job_detail/256683?action=view-source sa ia 100 de puncte?
E doar dijkstra simplu, fara heap. Care e complexitatea finala?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Cezar Mocan din Martie 09, 2009, 09:57:49
Ala nu e Dijkstra, e Bellman-Ford (cred :) )


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Philip din Martie 09, 2009, 10:04:12
Ala nu e Dijkstra, e Bellman-Ford (cred :) )
Si coada unde e?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Bogdan-Cristian Tataroiu din Martie 09, 2009, 11:33:25
Bellman Ford original nu e cu coada: Se parcurg toate muchiile i, j si se updateaza de fiecare data costul nodului j daca costul nodului i + costul muchiei e mai mic decat costul curent al nodului j si se repeta asta de N-1 ori. Coada e doar o optimizare.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Philip din Martie 09, 2009, 12:10:57
Bellman Ford original nu e cu coada: Se parcurg toate muchiile i, j si se updateaza de fiecare data costul nodului j daca costul nodului i + costul muchiei e mai mic decat costul curent al nodului j si se repeta asta de N-1 ori. Coada e doar o optimizare.
Stiu ca e doar o optimizare. Intrebarea mea era cum reuseste sa ia 100 de puncte, neoptimizat.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Pripoae Teodor Anton din Martie 09, 2009, 12:22:21
Sunt testele proaste daca nu ma insel, programul se bazeaza pe faptul ca nu o sa faca mai mult de logN operatii repeat. Fiecare repeat are complexitatea o(m). Daca dau un test de forma:

Cod:
10 11
3 2 1
4 3 1
5 4 1
6 5 1
7 6 1
8 7 1
9 8 1
10 9 1
11 10 1
1 11 1
1 2 10000000

Va face N operatii repeat.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Philip din Martie 09, 2009, 14:43:04
OK, am inteles. Mersi!


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Prigoana Cristian din Aprilie 08, 2009, 10:41:47
ciudat, am rezolvat-o de 40 puncte (cel putin asa cred) dar imi da TLE pe testele 2, 3, 4, care in mod normal nu are de ce. daca dau copy, paste in fisieru de intrare la mine pe calculator, merge fara probleme ...  ??? nu ar trebui sa se comporte la fel?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Cotofana Cristian din Aprilie 08, 2009, 20:08:50
imi poate spune si mie cineva dc cu sursa asta am luat 100?
http://infoarena.ro/job_detail/280886
daca va uitati la functia percolate variabila father ramane una si aceeasi, nu se modifica in interiorul whilelului
is testele chiar in halu ala de slabe :)?, ca la alte probleme unde trebea heap ma uitam la sursa asta sami amintesc functiile sift si percolate si luam doar 10-20 de pct tocmai din cauza acestei greseli
(sau is io batut in cap si numi inteleg propriul cod :D)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Andrei Misarca din Octombrie 17, 2009, 22:14:55
Am și eu o nelămurire. Cu sursa asta (http://infoarena.ro/job_detail/357107?action=view-source) obțin 100 de puncte, însă dacă renunț să mai marchez un nod ales cu distanța cea mai mică până în acel moment ca fiind neintrodus în heap, iau 60 (http://infoarena.ro/job_detail/357120?action=view-source). Deci un nod mai poate fi introdus în heap după l-am vizitat odată? Destul de ciudat, având în vedere că la fiecare pas extrag nodul cu distanța minimă.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Mircea Dima din Octombrie 18, 2009, 20:26:53
Am și eu o nelămurire. Cu sursa asta (http://infoarena.ro/job_detail/357107?action=view-source) obțin 100 de puncte, însă dacă renunț să mai marchez un nod ales cu distanța cea mai mică până în acel moment ca fiind neintrodus în heap, iau 60 (http://infoarena.ro/job_detail/357120?action=view-source). Deci un nod mai poate fi introdus în heap după l-am vizitat odată? Destul de ciudat, având în vedere că la fiecare pas extrag nodul cu distanța minimă.

Tu faci Lazy Dijkstra ...

Tu updatezi doar daca nu mai ai nodul in PriorityQueue... ceea ce nu e bine
(adica heapul nu se reface... dar distanta da)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Andrei Misarca din Octombrie 18, 2009, 20:45:44
Adică Lazy Dijkstra nu mai garanteaza O(M logN)?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Mircea Dima din Octombrie 18, 2009, 20:48:16
ba garanteaza (cred ca e MlogM ... nu sunt sigur)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Moldovan Marcel din Ianuarie 25, 2010, 12:52:44
M-am uitat peste unele surse si am observat ca se declara vectorul cu muchii de 250002 elemente, insa maximul de muchii este 250000. Este necesar acest lucru sau la ce ajuta? Eu am rezolvat problema folosind un vector cu 250000 de pozitii.

Am inteles. Mersi pentru raspunsuri!


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Gabriel Bitis din Ianuarie 25, 2010, 13:19:58
Unii declara tablourile cu 2-3 elemente in plus, pentru siguranta. Se poate intampla sa declari fix, si sa depasesti spatiul declarat daca nu esti atent si nu indexezi de la 0, sau cine stie din ce alte motive.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: alexandru din Ianuarie 25, 2010, 15:49:57
M-am uitat peste unele surse si am observat ca se declara vectorul cu muchii de 250002 elemente, insa maximul de muchii este 250000. Este necesar acest lucru sau la ce ajuta? Eu am rezolvat problema folosind un vector cu 250000 de pozitii.
Nu este bine sa declari un vector exact de cat ai nevoie, poate sa crape programul. Daca este lucat in considerarea faptul ca vectorul este indexat de la 0 la n-1 atunci e ok, dar da incepi de la 1 o sa ai surprize :P.

  


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Stefan-Alexandru Filip din Ianuarie 25, 2010, 16:45:10
M-am uitat peste unele surse si am observat ca se declara vectorul cu muchii de 250002 elemente, insa maximul de muchii este 250000. Este necesar acest lucru sau la ce ajuta? Eu am rezolvat problema folosind un vector cu 250000 de pozitii.
Nu este bine sa declari un vector exact de cat ai nevoie, poate sa crapa programul. Daca este lucat in considerarea faptul ca vectorul este indexat de la 0 la n-1 atunci e ok, dar da incepi de la 1 o sa ai surprize :P.

In general cred ca este bine sa declari vectorul exact atat cat iti trebuie, dar in cazul rezolvarii problemelor pentru olimpiada o neatentie te poate costa scump, asa ca multi prefera sa fie de partea sigura a baricadei si declara vectorii mai mari pentru ca se intampla de multe ori sa accesezi ceva care este la pozitia n+1 sau n+2.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: George Popoiu din Ianuarie 29, 2010, 11:08:31
Am facut Dijkstra clasic si am luat 40pct. Imi poate explica cineva ce ar trebui sa fac cu heap-ul? Ca nu reusesc sa ma prind :sad:

Intuiesc ca avem nevoie de un min-heap la care sa tinem in varf dinstanta de la nodul sursa la cel mai apropiat nod, dar nu imi dau seama cum ar trebui manipulat.

Multumesc anticipat !


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Marius Stroe din Ianuarie 29, 2010, 13:04:04
Am facut Dijkstra clasic si am luat 40pct. Imi poate explica cineva ce ar trebui sa fac cu heap-ul? Ca nu reusesc sa ma prind :sad:

Intuiesc ca avem nevoie de un min-heap la care sa tinem in varf dinstanta de la nodul sursa la cel mai apropiat nod, dar nu imi dau seama cum ar trebui manipulat.

Multumesc anticipat !

Fiecare nod din heap poate fi considerat ca o pereche (x, d), unde „x” reprezintă un nod din graf care se găseşte la distanţa „d” faţă de nodul sursă. Algoritmul lui Dijkstra presupune să obţii de „n-1” ori cel mai apropiat nod de sursă. Astfel, în vârful heapului ai cel mai apropiat nod de nodul sursă, dacă ţii heapul pe baza distanţelor. Extragi această pereche din vârful heapului, operaţie pe care o înveţi din manual dacă nu o ştii, după care relaxezi fiecare vecin al nodului tocmai obţinut. Se va întâmpla să relaxezi doar nodurile care încă mai sunt în heap, deoarece restul au distanţa mai mică iar muchiile au costuri pozitive. Când relaxezi un nod, acesta urcă în heap cât timp are o distanţă mai mică decât părintele său. E posibil să ajungă în vârf astfel. Repeţi procedeul. :)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: alexandru din Ianuarie 29, 2010, 13:27:42
Am facut Dijkstra clasic si am luat 40pct. Imi poate explica cineva ce ar trebui sa fac cu heap-ul? Ca nu reusesc sa ma prind :sad:

Intuiesc ca avem nevoie de un min-heap la care sa tinem in varf dinstanta de la nodul sursa la cel mai apropiat nod, dar nu imi dau seama cum ar trebui manipulat.

Multumesc anticipat !
Faci exact ca la problema Heap ;)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: George Popoiu din Ianuarie 29, 2010, 14:55:19
Multumesc Marius si alexandru pentru raspunsuri, am inteles rezolvarea, dar cu toate acestea iau 90pct. (WA pe testul 1)

Nu inteleg ce este gresit in sursa mea, desi am recitit-o de peste 10 ori.

Daca aveti timp sa aruncati o privire si sa vedeti ce este gresit as fi recunoscator, deoarece ma "sacaie" ideea de 90pct la o problema ce am impresia ca i-am inteles rezolvarea.

Sursa este comentata, asa ca nu ar trebui sa fie greu de inteles.

http://infoarena.ro/job_detail/388169?action=view-source


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Paul-Dan Baltescu din Ianuarie 29, 2010, 14:59:15
Accesul la testele problemelor din arhiva educationala este liber. Poti sa-ti downloadezi testul si sa vezi ce nu iti merge.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: alexandru din Ianuarie 29, 2010, 15:44:46
Esti sigru ?
Chiar acum am downladat testul si am rulat sursa ta. In loc sa afiseze 10 la penultima valoare, pune 14. Fa un debug ;)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: George Popoiu din Ianuarie 29, 2010, 16:19:45
Am rezolvat, chiar era un bug, merci Alexandru !


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Arnold Tempfli din Februarie 23, 2010, 09:21:34
cu priority queue poate cineva sa obtine 100p?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Andrei Misarca din Februarie 23, 2010, 12:28:49
cu priority queue poate cineva sa obtine 100p?
Da. http://infoarena.ro/job_detail/357124


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Grigore Cezar din Februarie 23, 2010, 18:54:26
Ma poatea ajuta si pe mine cineva sa iau 100 la sursa asta va rog    http://infoarena.ro/job_detail/401756?action=view-source
momentan imi iese din ultimul test dar nu stiu ce as putea sa-i mai fac


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Tuchila Octavian din Martie 20, 2010, 22:26:25
cod :

while(h.size() && pas<=1LL*n*m)

ce inseamna 1LL ?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Dragos-Alin Rotaru din Martie 20, 2010, 22:29:50
Il pui pe 1 tip long long. E ca o conversie a inmultirii.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: S. Alex din Martie 31, 2010, 14:49:12
merge si bellman ford varianta primitiva fara coada si nimic relaxezi muchii pana nu mai poti si iei 100 ! ironia sortii :D


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Gabriel Bitis din Martie 31, 2010, 14:55:53
Scopul problemei Algoritmul lui Dijkstra, e sa inveti algoritmul lui Dijkstra.  :aha:


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: S. Alex din Martie 31, 2010, 15:47:31
evident, am facut si eu cu multiset si am luat 80 si ma multumesc cu atat.. defapt nu inteleg de ce set-urile din STL iau mai putin adica de ce ar fi mai ineficiente, in fine, consider ca daca iei toate in considerare ( lungimea sursei, timpu necesar implementarii si rezultatele in sine ) atunci e mai bine la un concurs sa alegi sa implementezi cu STL pt ca e mai simplu si ai timp pt celelalte chestii sa zic asa, acuma depinde si asta, daca unu o implementat nush cate probleme cu heapuri facute manual, cred si eu ca nu o sa fol STL, dar pt altii optiunea e clara


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: alexandru din Martie 31, 2010, 16:03:31
Un lucru ce are putea cauza ineficienta ar fi OOP. Poti folosi make_heap, pop_heap, push_heap, pentru a gestiona un heap. :)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: S. Alex din Martie 31, 2010, 17:41:02
hm.. am facut folosind chestiile alea.. si am luat mai putin  :D adica am luat TLE la mai multe si nu cred ca am facut io gresit ceva adica am transformat sursa cu multiseturi intr-una folosind chestiile de care ziceai tu nimic altceva, lasa ca e bine si 80 cu multiseturi   :?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Mircea Dima din Martie 31, 2010, 21:43:03
Ineficienta vine de la faptul ca set/multiset sunt implementat folosind Red-Black Trees, iar acestia au o constanta mult mai mare decat cea a unui heap. Cu functiile alea push_heap / pop_heap ar trebui sa poti lua 100.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Balan Radu Cosmin din August 01, 2010, 18:54:49
Am scris un Dijkstra normal, am luat 50 de puncte.
Am incercat apoi un Dijkstra cu heapuri, iese din timp la ultimul test si iau 90, iar in final cu un bellman cu coada si acelasi rezultat, iese din timp la ultimul test.
Probabil implementarea mea cu heapuri nu e optima.
Poate cineva sa arunce o privire si sa-mi dea un sfat?
[LE]
Am inteles unde gresesc la bellman, eu inserez nodul chiar daca este deja in coada,
dar la dijktra cu heapuri tot am intrebari.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: SAlexandru din August 01, 2010, 21:00:22
Implementeaza push_down iterativ si apoi vezi ce se intampla ;)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Balan Radu Cosmin din August 01, 2010, 23:03:35
aha... am sa incerc... ma gandeam ca motivu pt care pierd ceva timp e ca.. in bellman folosesc coada in stl.. in loc sa o implementez eu... iar in ambele cazuri.. reprezentarea grafului sub forma de vectori in stl.. si ma gandesc ca poate.. o reprezentare dinamica cu liste de adiacenta ar fi mai rapida


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Vlad Eugen Dornescu din August 02, 2010, 01:10:10
Salut, m-am uitat eu peste sursa ta.Modificarea consta in faptul ca am folosit un vector<pair<int, int>> in loc de 2 vectori dinamici de dimensiune NMAX pentru a retine vecinii nodului, respectiv costul muchiei dintre acestia.
Am observat ca la inceput calculai si un numar de aparitii, desi nu e nevoie. (Am sters si portiunea aia de cod)
Uite sursa ta de 100 puncte :
http://infoarena.ro/job_detail/474034?action=view-source


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Balan Radu Cosmin din August 02, 2010, 11:32:21
deci faptu ca retineam graful sub forma a doi vectori manca timpu.. si daca folosesc unul singur cu pair<> se rezolva.. multumesc mult pt timpu acordat
[LE] si partea cu numarul de aparitii pe care ai mentionat-o , din cate stiu n-am folosit nimic de genul acesta ... dar oricum.. acea modificare.. din 2 vectori cu unu pair... a rezolvat problema:D multumesc
[LE].. ahh am inteles . dar acea chestie care zici ca numara aparitiile era folosit p postul de un vector true false, desi era declarat int... era ceva memorie irosita ce-i drept.. dar l-am schimbat in unul bool


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Paunel Cosmin din Septembrie 01, 2010, 21:38:06
Eu nu inteleg cum se ia 90 de pct cu 2 vectori separati din stl,iar cu un vector de pair<long,long> se ia 100.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Balan Radu Cosmin din Septembrie 08, 2010, 16:48:00
atunci cand tii unul pair faci o singura inserare pe muchie si nu doua ma gandesc eu.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: George Marcus din Octombrie 22, 2010, 22:59:08
Ma tot chinuiam sa gasesc vreo optimizare la programul meu pentru ca luam 90 de puncte si la ultimul test depasea timpul. Dupa cam o ora de cautari printre sursele altora mi-am dat seama ca in mare sunt la fel. Am gasit solutia in final printr-o amarata comanda de settextbuf. Doar recent am auzit de aceasta de la alti membri printre comentarii, dar habar nu aveam ca poate sa faca o asemenea diferenta. In sfarsit 100!  :banana: =D&gt;


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Tirca Bogdan din Ianuarie 21, 2011, 00:10:44
Este exagerata limita de timp, din cate am vazut intra mai bine o coada simpla decat un heap.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Andrei Geogescu din Ianuarie 25, 2011, 19:33:40
Conform "verificatorului" acest algoritm este gresit (wrong answer)

Asa fiind...poate sa'mi explice cineva unde imi este gresit rationamentul ?

Cod:
#include<iostream.h>
#include<fstream.h>
long long a[9000][9000];
int main()
{int i,j,k,n,m,x,y,z;

ifstream f("dijkstra.in");
ofstream h("dijkstra.out");
f>>n>>m;

for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
a[i][j]=10000;


for(i=1;i<=m;i++)
{ f>>x>>y>>z;
a[x][y]=z;}
for(k=1;k<=n;k++)
for(j=1;j<=n;j++)
 if(a[1][k]+a[k][j]<a[1][j]&&i!=k&&j!=k)
a[1][j]=a[1][k]+a[k][j];
for(i=2;i<=n;i++)
h<<a[1][i]<<" ";


return 0;}
Modificat de Moderator: Nu mai posta consecutiv si foloseste tag-ul [ code ] ... [ / code ] cand scrii surse


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Paul-Dan Baltescu din Ianuarie 25, 2011, 22:25:00
Fara sa ma uit prea atent observ doua probleme majore in programul tau: folosesti prea multa memorie si complexitate timp prea mare. In rest, poti lua testele (sunt publice) si sa vezi unde nu-ti da bine.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Bompa Mario din Ianuarie 31, 2011, 20:50:43
imi poate spune si mie cineva de ce imi da incorect pe acest cod daca rezultatul e la fel cu cel de la raspunsuri
Cod:
#include<fstream>
#include<cstdio>
#include<vector>
#include<utility>
#define ff it->first
#define ss it->second

using namespace std;
int n,m,a,b,c,d[50005],oo=500000000,h[50010],poz[50010],i,l,nod,dist;
void read(),solve(),percolate(int t),sift(int f);
vector <pair<int,int> > v[50010];


int main()
{

read();
solve();
return 0;
}
void read()
{
ifstream in("dijkstra.in");
in>>n>>m;
for(;m;m--)
{
in>>a>>b>>c;
v[a].push_back(make_pair(b,c));
}
in.close();
}
void solve()
{
vector<pair<int,int> >::iterator it;
ofstream out("dijkstra.out");
for(i=1;i<=n;i++)
{
h[i]=i;
d[i]=oo;
poz[i]=i;
}
d[1]=0;
l=n;
for(;l;)
{
nod=h[1];
dist=d[nod];
for(it=v[nod].begin();it!=v[nod].end();it++)
if(d[ff]>dist+ss)
{
d[ff]=dist+ss;
percolate(poz[ff]);
}
h[1]=h[l];
poz[h[1]]=1;
l--;
sift(1);
}
for(i=2;i<=n;i++)
{
if(d[i]==oo)
d[i]=0;
}
for(i=2;i<=n;i++)
out<<d[i]<<" ";
out.close();
}
void percolate(int f)
{
int t,aux;
for(;;)
{
t=f>>1;
if(d[h[t]]<=d[h[f]])
return;
aux=h[t];
h[t]=h[f];
h[f]=aux;
poz[h[t]]=t;
poz[h[f]]=f;
f=t;
}
}
void sift(int t)
{
int f,aux;
for(;;)
{
f=t<<1;
if(f>l)
return;
if(f<l)
if(d[h[f]]<d[h[f+1]])
f++;
if(d[h[t]]<=d[h[f]])
return;
aux=h[t];
h[t]=h[f];
h[f]=aux;
poz[h[t]]=t;
poz[h[f]]=f;
t=f;
}
}


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: George Marcus din Februarie 01, 2011, 00:21:32
Daca iti da corect pe exemplul de la problema nu inseamna ca iti da pentru toate :)

Nu introdu toate nodurile de la inceput, doar pe cele pe care le-ai vizitat. Le introduci pe parcurs pe fiecare.
Asta e greseala cea mai mare... In rest, am modificat <= in < si >= in > (nu ma intreba de ce, dar a facut diferenta de la 80 la 90...). N-am putut pana la 100, dar vezi tu...

Sursa ta modificata: http://infoarena.ro/job_detail/527679?action=view-source


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Bompa Mario din Februarie 01, 2011, 08:48:03
bine dar faza este ca mie imi afiseaza ce trebuie la primul exemplu dar imi zice ca e incorect shi imi ia 10 puncte pe la testu 7
http://infoarena.ro/job_detail/527540 (http://infoarena.ro/job_detail/527540) asta e mesajul de la evaluator ](*,)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Gabriel Bitis din Februarie 01, 2011, 10:49:12
Sa inteleg ca pe testul asta :

Cod:
7 9
1 4 2
1 2 1
2 3 3
4 3 1
3 5 2
5 6 5
6 3 1
3 7 2
1 5 9

rezultatul tau e
Cod:
1 3 2 5 10 5 

si iei 0 puncte pe primul test?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: George Marcus din Februarie 01, 2011, 13:29:29
Nu iti afiseaza ce trebuie... Am verificat si eu inainte.

Iti da asa la primul: 1 3 2 5 14 5

Mai verifica odata :)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Bompa Mario din Februarie 02, 2011, 20:55:19
Eu ma gandeam ca este ca la .campion...primul test este ca cel din exemplu shi ala imi dadea bine shi de asta...
Gata am rezolvat ms mult de help :)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Paun Georgel din Martie 13, 2011, 11:35:32
am si eu o intrebare
Cod:
#include <cstdio>
#include <list>
#include <set>

using namespace std;

int n,m;
int d[50002],inms[50002];

struct Compar{
bool operator()(int i,int j){
return d[i]<d[j];
}
};

list<pair<int,int> > l[50002];
list<pair<int,int> >::iterator it;
multiset<int ,Compar> ms;

void citire(){
scanf("%d %d",&n,&m);
int i,x,y,c;
for(i=1;i<=m;i++){
scanf("%d %d %d" , &x,&y,&c);
l[x].push_back(make_pair(y,c));
}
}

void dijkstra(int rad){
int i,poz;
for(i=1;i<=n;i++){
d[i]=1000000000;
inms[i]=0;
}
inms[rad]=1;
d[rad]=0;
ms.insert(rad);
while(!ms.empty()){
poz=*ms.begin();
ms.erase(ms.begin());
inms[poz]=0;
for(it=l[poz].begin();it!=l[poz].end();++it)
if(d[(*it).first]>d[poz]+(*it).second){
if(inms[(*it).first]==1){
ms.erase((*it).first);
}
else {
inms[(*it).first]=1;
}
d[(*it).first]=d[poz]+(*it).second;
ms.insert((*it).first);

}
}
}

void afisare(){
int i;
for(i=2;i<=n;i++)
if(d[i]!=1000000000)
printf("%d ",d[i]);
else printf("0 ");
printf("\n");
}

int main(){
freopen("dijkstra.in","r",stdin);
freopen("dijkstra.out","w",stdout);
citire();
dijkstra(1);
afisare();
return 0;
}

am luat testele si unele dimensiuni imi dau prea mari ... nu reusesc sa gasesc greseala


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Agape Mihai din Martie 21, 2011, 23:45:35
Salut!
De ieri tot încerc să fac un cod de 100 de puncte la această problemă, dar la fiecare implementare primesc TLE pe ultimul test. Am încercat mai multe variante:

Dijkstra cu heap - varianta fara STL (http://infoarena.ro/job_detail/561904?action=view-source)
Dijkstra cu heap - varianta cu STL (http://infoarena.ro/job_detail/561845?action=view-source)
Bellman-Ford cu coada - putin STL (http://infoarena.ro/job_detail/561935?action=view-source)
Bellman-Ford cu coada - mai mult STL (http://infoarena.ro/job_detail/561930?action=view-source)
Dijkstra cu coada de prioritati (http://infoarena.ro/job_detail/561629?action=view-source)

Am pus aici toate variantele, însă mi-ar fi suficient dacă m-aţi putea ajuta să corectez măcar una dintre ele. Merci anticipat :).


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Neagoe Alexandru din Martie 29, 2011, 20:03:13
Daca luati 80-90 cu TLE pe ultimele teste incercati sa faceti citirea cu streamuri. Asta a facut diferenta in cazul meu de la 80 la 100.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Popescu Marius din Martie 31, 2011, 21:01:46
Salut!
De ieri tot încerc să fac un cod de 100 de puncte la această problemă, dar la fiecare implementare primesc TLE pe ultimul test. Am încercat mai multe variante:

Dijkstra cu heap - varianta fara STL (http://infoarena.ro/job_detail/561904?action=view-source)
Dijkstra cu heap - varianta cu STL (http://infoarena.ro/job_detail/561845?action=view-source)
Bellman-Ford cu coada - putin STL (http://infoarena.ro/job_detail/561935?action=view-source)
Bellman-Ford cu coada - mai mult STL (http://infoarena.ro/job_detail/561930?action=view-source)
Dijkstra cu coada de prioritati (http://infoarena.ro/job_detail/561629?action=view-source)

Am pus aici toate variantele, însă mi-ar fi suficient dacă m-aţi putea ajuta să corectez măcar una dintre ele. Merci anticipat :).

Si eu m-am chinuit ca tine, am bagat mai multe variante, dar vad ca au micşorat limita de timp. Sursa mea de 100 de anu trecut, ia 80 anul asta  :-' . Cred ca trebuie facut cu zice Alexandru sa citesti cu streamuri sau sa parsezi citirea.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: George Marcus din Martie 31, 2011, 21:05:49
Eu n-am parsat citirea si nici n-am citit cu streamuri si iau 100. Ce-i drept, iau ultimul test cu 500ms = limita :) (da, stiu ca e doar un timp aproximativ)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Nicolae Titus din Aprilie 08, 2011, 06:50:16
a reusit cineva sa faca dijkstra de 100 cu make_heap, push_heap si pop_heap?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Mihai-Alexandru Dusmanu din Aprilie 08, 2011, 07:08:45
a reusit cineva sa faca dijkstra de 100 cu make_heap, push_heap si pop_heap?

Eu am facut cu priority_queue si a intrat in timp. M-am uitat pe sursa ta... Incearca sa citesti cu fstream pentru ca merge mai bine pe infoarena uneori :)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Nicolae Titus din Aprilie 08, 2011, 16:57:52
Eu am facut cu priority_queue si a intrat in timp. M-am uitat pe sursa ta... Incearca sa citesti cu fstream pentru ca merge mai bine pe infoarena uneori :)

Am optimizat toate maruntisurile si nu trece. La sursele mele prostia e ca vreau sa modific costul unui element din heap si sa-i mut pozitia in heap. Asta inseamna sa urmaresc pozitia tuturor elementelor in heap si sa folosesc cand trebuie sa le mut pozitia.
La sursa ta vad ca pur si simplu adaugi acelas nod dar cu alt cost. Daca are distanta mica atunci ajunge in varful heapului, daca nu, se pierde si nu ajunge sa-l procesezi vreodata. O sa incerc make_heap cu idea ta sa vad ce iese.
Multumesc!


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Macarescu Sebastian din Aprilie 26, 2011, 12:26:34
S-a micsorat limita de timp? Sursa http://infoarena.ro/job_detail/357124?action=view-source (http://infoarena.ro/job_detail/357124?action=view-source) lui Andrei Misarca  acum ia numai 90 de puncte http://infoarena.ro/job_detail/584692?action=view-source (http://infoarena.ro/job_detail/584692?action=view-source)  :-k. A mai reusit cineva sa ia 100 cu priority_queue recent? Eu nu reusesc sa scot mai mult decat 50, restul TLE  ](*,).
Puteti sa va puteti uita peste sursa http://infoarena.ro/job_detail/584658?action=view-source (http://infoarena.ro/job_detail/584658?action=view-source) si eventual sa imi spuneti ce sa mai optimizez ?
Multumesc anticipat.

LE: Am descoperit ce nu mergea. Nu inteleg dc trebuie  In loc de < sa pun > pentru a-mi tine elementele sortate crescator.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Heidelbacher Andrei din Iunie 06, 2011, 16:51:47
Am o problema cu algoritmul lui dijkstra folosind heap-urile... Am implementat exact cum este explicat algoritmul, dar iau doar 90 de puncte (pe ultimul test iau TLE), se poate uita cineva peste ultima sursa pe care am trimis-o si sa imi spuna ce am putut gresi sau ce pot eficientiza? Multumesc anticipat.

Link-ul pentru sursa este urmatorul:
http://infoarena.ro/job_detail/594225?action=view-source


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Oancea Catalin din Iunie 06, 2011, 19:24:47
incearca sa modifici citirea... in rest pare ok


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Heidelbacher Andrei din Iunie 06, 2011, 20:01:32
Am incercat sa fac cu citirile din C, dar asa iau 80 de puncte  ](*,)
Daca ai vrut sa spui altceva in legatura cu citirea, te rog fii putin mai explicit. Multumesc.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: cont cu nume gresit sau fals din Iunie 06, 2011, 20:34:07
in loc de *2 pune <<1 si in loc de /2 pune >>1
astea sunt operatii pe biti si reprezinta shiftarea numarului la stanga sau la dreapta
l.e.:
trebuia sa verific daca ce spun are efecte majore.
ceea ce am spus mai sus nu te ajuta aici, dar cine stie.
ideea este sa-ti faci un struct edge{int dest,cost};
si in loc de
Cod:
vector <long> G[50005];
vector <long> C[50005];
sa ai
Cod:
vector <edge> G[50005];

ti-am modificat sursa si ia acum 100:
http://infoarena.ro/job_detail/594291 (http://infoarena.ro/job_detail/594291) 8)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: MciprianM din Iulie 15, 2011, 09:31:49
Merge de 100 de puncte si un algoritm in O(V*sqrt(V)+E) - sursa (http://infoarena.ro/job_detail/603249?action=view-source).


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Sorin Rita din Iulie 19, 2011, 20:30:22
Cod:
 graf *t = a[pmin];

        while ( t )
        {
            if ( d[ t->nod ] > d[pmin] + t->cost )
                d[ t->nod ] = d[pmin] + t->cost;

            t = t->next;
        }
imi poate explica si mie cineva,linie cu linie, bucata asta de cod din sursa de 40 ?  :?

 Foloseste tag-ul [ code ] [ /code ] cand postezi cod!


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: George Marcus din Iulie 19, 2011, 20:44:05
Cod:
graf *t = a[pmin];  // declaram un pointer caruia ii atribuim adresa listei cu vecinii nodului pmin (care e cel mai apropiat nod dintre cei nevizitati)

        while ( t ) // cat timp n-am ajuns la capatul listei
        {
            if ( d[ t->nod ] > d[pmin] + t->cost )  // daca drumul catre vecinul curent care trece prin pmin este unul mai scurt decat cel calculat pana acum
                d[ t->nod ] = d[pmin] + t->cost;   //  atribuim noua distanta

            t = t->next; // trecem la urmatorul vecin al lui pmin
        }


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Sorin Rita din August 06, 2011, 22:22:07
Merge si pe grafuri neorientate daca la citire adaug ?

Cod:
 add(y,x,z); 


L.E. : si se poate sa opresc algoritmul cand am ajuns la un anumit nod final ? Daca da, cum ?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Mircea Dima din August 06, 2011, 22:53:23
Merge pe grafuri neorientate.
Cred ca te poti opri la un anumit nod final atunci cand ai relaxat toate muchiile catre acel nod.
Totusi nu cred ca vei imbunatati prea mult algoritmul.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Ion Vlad-Doru din Noiembrie 09, 2011, 22:11:45
Are cineva vreo idee ce as putea sa fac sa imi intre in timp pe ultimu test? Deja cred ca o iau cu capu  :angry:


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Ion Vlad-Doru din Noiembrie 10, 2011, 21:23:33
Am trimis si sursa oficiala si nici ea nu ia 100 de puncte. Cred ca ar trebui sa modifice cineva timpul maxim de executie.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Sunt emo din Noiembrie 10, 2011, 22:32:41
Nici sursa mea nu reuseste sa se incadreze in timp. De fapt ma mira faptul ca iau alte surse de 100 de puncte (destul de recente), le retrimit si acum nu iau decat 80-90p. Am implementat Dijkstra cu heap, am optimizat tot ce se putea (in limita geniului meu )) ) si degeaba :(


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Sunt emo din Noiembrie 10, 2011, 23:49:11
Apropo, imi explica cineva cum sursa http://infoarena.ro/job_detail/629253?action=view-source ia suta? Cred ca is atat de bune testele ...


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Sorin Rita din Decembrie 02, 2011, 18:45:49
Se mai poate lua 100 fara parsare ? N-ar strica marita putin limita de timp..


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Ababab din Februarie 16, 2012, 21:53:25
Se poate șterge ultima mea sursă trimisă pentru problema asta? Am încurcat problemele.  :rotfl:


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Andrei Geogescu din Martie 25, 2012, 16:59:57
http://infoarena.ro/job_detail/723601?action=view-source


as fi deosebit de recunoscator celui ce isi va dedica o mica parte din timpul sau pentru a'mi explica ce anume este gresit la aceasta sursa



Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: George Marcus din Martie 25, 2012, 17:30:13
Nimeni nu isi va dedica timp sa iti citeasca sursa in halul in care este scrisa. Ar fi bine sa urmezi sfaturile de aici (http://en.wikipedia.org/wiki/Programming_style).


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Popa Mihai din Martie 25, 2012, 19:16:11
In cazul in care afisezi 0, in loc de '0 ' trebuie sa pui "0 ".


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Andrei Geogescu din Martie 25, 2012, 19:34:38
iti mulrumesc..
si totusi, am luat 50 p, iesindu'mi din timp


Titlul: Salut
Scris de: Pirvanescu Livius din Martie 26, 2012, 17:27:41
Am incercat sa rezolv problema cu algoritmul lui Bellman-Ford (sursa ia 100 pct ) insa nu stiu de ce nu iau mai mult de 10pct aici ,pe restul testelor e incorect...
Daca aveti putin timp sa dati "o geana" pe cod as fi recunoscator :)

http://infoarena.ro/job_detail/724636?action=view-source (http://infoarena.ro/job_detail/724636?action=view-source)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Gabriel Bitis din Martie 26, 2012, 17:30:05
Testele problemei sunt publice. Ai putea sa downloadezi testele mici si sa vezi ce rezultate scoate programul tau.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Laurentiu Ion din Martie 26, 2012, 17:38:05
Am incercat sa rezolv problema cu algoritmul lui Bellman-Ford (sursa ia 100 pct ) insa nu stiu de ce nu iau mai mult de 10pct aici ,pe restul testelor e incorect...
Daca aveti putin timp sa dati "o geana" pe cod as fi recunoscator :)

http://infoarena.ro/job_detail/724636?action=view-source (http://infoarena.ro/job_detail/724636?action=view-source)

Aruncand un ochi rapid pe sursa ta, trebuie sa verifici/adaugi in coada vecinu' doar daca are distanta mai mica, pe cand tu ai if-ul ala in afara primului, baga-l inauntru.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Pirvanescu Livius din Martie 26, 2012, 20:41:19
if (d[a[nod].n]>d[nod]+a[nod].c)
            {
            d[a[nod].n]=d[nod]+a[nod].c ;
          if (inq[a[nod].n]==false)
             {q.push(a[nod].n);inq[a[nod].n]=true;}
            
           }


Se pare ca erau acolo parantezele :)Multumesc oricum!

L.E. Imi e rusine sa spun care era problema! :)) out>>"0" in loc de out>>"0 " ...
Multumesc pentru ajutor!


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Laurentiu Ion din Martie 26, 2012, 20:49:18
mda, pai aici trebuie sa te inveti si tu sa codezi frumos... din indentare parea ca if-urile alea 2 sunt separate :annoyed:


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Visan Radu din Aprilie 16, 2012, 11:41:12
Imi puteti spune si mie va rog ce mai pot optimiza la sursa asta http://infoarena.ro/job_detail/735388?action=view-source ? Am facut cu priority queue, cu stream-uri si tot iau TLE pe 3 teste, al 4-lea test gresit are incorect.


Multumesc!


LE: nu am mai dat edit atunci, am facut-o de 100.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Dan H Alexandru din Iulie 12, 2012, 14:54:13
http://infoarena.ro/job_detail/766985?action=view-source

Aveti idee ce poate fi gresit ? Dijkstra cu heap-uri. Tin sa mentionez ca , cu acelasi cod putin modficiat la complexitate O(M lg M) iau 90 cu un TLE.

Multumesc anticipat !  :ok

LE: Solved.  :ok:


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Bodnariuc Dan Alexandru din Iulie 16, 2012, 20:39:18
ma poate ajuta si pe mn cineva numi dau seama ce greseste programu. am facut cu bellman ford.
iau KBS si incorect http://infoarena.ro/job_detail/768454?action=view-source


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Visan Radu din Iulie 16, 2012, 21:03:04
In primul rand, la BellmanFord adaugi in coada un nod nou daca nu e deja in coada, pt asta tii inca un vector. Alta observatie, in loc de deque poti folosi direct queue. Mi se pare ca trebuie sa folosesti .size() in loc de .capacity() la forul de la BellmanFord.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Bodnariuc Dan Alexandru din Iulie 16, 2012, 21:16:49
nu nu asta era problema nu trebe nici un vector. problema venea de la ceai zis tu cu size() in loc de capacity() .. nuntaleg care e diferenta:X
thnx


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Visan Radu din Iulie 16, 2012, 21:27:38
Aia cu coada era o varianta mai simpla. Uite aici ai diferenta intre capacity si size: http://www.cplusplus.com/reference/stl/vector/capacity/ http://www.cplusplus.com/reference/stl/vector/size/


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Grajdeanu Alexandru din August 31, 2012, 17:35:36
Stie cumva,cineva daca se poate face si prin backtracking? Multumesc anticipat ! :D


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: George Marcus din August 31, 2012, 19:41:15
Se poate. Dar timpul de executie va fi extrem de mare.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Alexandru Valeanu din Aprilie 13, 2013, 16:56:02
Am si eu o curiozitate daca N < 1000 si M < N*N este mai buna varianta N*N sau cea MlogN ( teoretic cea N*N ) e mai buna pe cazul maxim nu?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Mihai Calancea din Aprilie 13, 2013, 17:04:49
Da, pe grafuri dense brutul bate M log N-ul. La fel si Prim-ul in N ^ 2 bate ceilalti algoritmi de APM :)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Alexandru Valeanu din Aprilie 13, 2013, 17:13:25
Mersi mult de raspuns


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Aiordachioaei Marius din August 18, 2013, 20:24:31
spuneti-mi va rog de ce sursa asta http://www.infoarena.ro/job_detail/985164?action=view-source are TLE pe 5 teste? folosesc o coada de prioritate in loc de heap, iar daca inlocuiesc priority_queue-ul cu un queue simplu intra in timp. Multumesc anticipat


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Pirtoaca George Sebastian din August 18, 2013, 21:17:22
Tu iei TLE deoarece incerci sa relaxezi muchiile incidente unui nod de mai multe ori. Foloseste un vector caracteristic. Iar atunci cand inlocuiesti coada de prioritati cu o coada normala, tu de fapt faci Bellman Ford.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Cosmin Rusu din August 19, 2013, 17:22:42
spuneti-mi va rog de ce sursa asta http://www.infoarena.ro/job_detail/985164?action=view-source are TLE pe 5 teste? folosesc o coada de prioritate in loc de heap, iar daca inlocuiesc priority_queue-ul cu un queue simplu intra in timp. Multumesc anticipat

Pentru ca sa implementezi Dijkstra pe Heap-uri ai nevoie de un Min-Heap !
priority_queue < type > e max-heap. Pentru a implementa Min-Heapul folosind STL faci asa:

Cod:
priority_queue <nod, vector<nod> , greater<nod> > MINHEAP;
Sau iti poti face propria ta clasa de comparare, ca aici: http://www.cplusplus.com/reference/queue/priority_queue/priority_queue/

Pentru mai multe informatii consulta asta : http://www.cplusplus.com/reference/queue/priority_queue/ .

Spor!


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Balan Radu Cosmin din August 27, 2013, 02:43:00
Sursa http://www.infoarena.ro/job_detail/989978 (http://www.infoarena.ro/job_detail/989978) cu Set de la indicatii ce ar trebui sa obtina 80 de puncte acum scoate 90-100 la limita.
Si de mentionat ca o imbunatatire ar fi eliminarea intrarii din set si inserarea unei intrari noi atunci cand actualizam distanta unui nod.

Noii timpi obtinuti : http://www.infoarena.ro/job_detail/989976 (http://www.infoarena.ro/job_detail/989976)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Alexandru Valeanu din August 27, 2013, 17:24:54
Asta pentru ca poate a fost imbunatatit compilatorul...


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Alexandru Valeanu din August 28, 2013, 17:17:43
Am si eu o nelamurire: Dijkstra cu costuri mici implementat ca in articolul din GInfo ia 70p cu 3 TLE. Daca scot functia de stergere din vechea lista ( ceea ce teoretic este o greseala ) ia 100p. Asa ar trebui sa se intample sau nu sunt propuse testele astfel incat astfel de solutii sa nu ia 100?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: CHIRILA ADRIAN din Octombrie 29, 2013, 22:16:33
Killed by signal 11(SIGSEGV)-Ce semnifica mesajul ?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Rares Cheseli din Octombrie 29, 2013, 23:01:04
Killed by signal 11(SIGSEGV)-Ce semnifica mesajul ?

Citeste aici http://www.infoarena.ro/documentatie/evaluator la Mesaje de evaluare


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Raul Butuc din Februarie 28, 2014, 23:07:23
Hm.. Dacă vă rog, îmi poate spune și mie cineva de ce nu e bun codul meu? Iau doar 10 pct.. Ideea algoritmului am luat-o de pe TopCoder dintr-un tutorial. Era un Dijkstra rezolvat pe baza unui priority_queue<T, vector<T> >. Pe toate testele pe care i le-am dat, rulează ok, nu înțeleg de unde provine problema.

http://www.infoarena.ro/job_detail/1131352?action=view-source

EDIT: TopCoder ref http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=standardTemplateLibrary2#dijkstra2

Mulțumesc anticipat.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Mircea Popoveniuc din Martie 01, 2014, 06:32:48
Citeste cu atentie restrictiile problemei ;)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Raul Butuc din Martie 01, 2014, 15:05:33
Citat
Restrictii
1 ≤ N ≤ 50 000
1 ≤ M ≤ 250 000
Lungimile arcelor sunt numere naturale cel mult egale cu 1 000.
Pot exista arce de lungime 0
Nu exista un arc de la un nod la acelasi nod.
Daca nu exista drum de la nodul 1 la un nod i, se considera ca lungimea minima este 0.
Arcele date in fisierul de intrare nu se repeta.

Deci, eu afisam INT_MAX pentru drumurile care nu exista, acum afisez 0 in schimb, dar tot nu primesc punctele :?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: George Marcus din Martie 01, 2014, 15:26:35
Nu ar trebui sa extragi intai nodurile cu distanta cea mai mica?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Raul Butuc din Martie 01, 2014, 16:58:26
Ah scuze, țin minte că scrisesem acea parte, dar cred că am șters-o ieri din greseală.. Mersi :)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Johny Deep din Aprilie 17, 2014, 07:43:43

Vă rog dacă poate să verifice cineva sursa:
http://www.infoarena.ro/job_detail/1172258?action=view-source (http://www.infoarena.ro/job_detail/1172258?action=view-source)

Timpii de rulare sunt foarte buni, dar la memoria folosită apare doar
memorie depăşită: http://www.infoarena.ro/job_detail/1172258 (http://www.infoarena.ro/job_detail/1172258)

Cum pot afla care este dimensiunea memoriei folosite?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Alexandru Valeanu din Aprilie 17, 2014, 13:28:01
Timpii de rulare sunt buni pentru ca programul nu este rulat pana la sfarsit, deoarece iese din memorie destul de repede din cauta reprezentarii grafului folosind cozi. Daca muti programul pe vector: http://www.infoarena.ro/job_detail/1172397?action=view-source o sa-ti intre in memorie. Pentru obiectele din STL nu poti calcula prea usor cata memorie consuma, de aceea e bine sa le eviti. Oricum citeste asta daca te intereseaza: http://stackoverflow.com/questions/7448514/how-can-i-know-how-much-memory-an-stl-object-takes si http://stackoverflow.com/questions/14784551/c-stl-queue-memory-usage-compared-to-vector


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Johny Deep din Aprilie 17, 2014, 19:42:11
Multumesc pentru ajutor, Alexandru!
Am gasit de unde era eroarea:
obiectele queue sunt alocate ineficient.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Witsel Andrei din August 07, 2014, 12:06:15
scz ca intreb, dar ce inseamna INF=1 << 30;??


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Visan Radu din August 07, 2014, 12:35:25
1 << 30 = 230
Ai aici (http://www.dponline.ro/articol.php?idarticol=81) un articol unde sunt explicate operatiile pe biti :)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Vlad Dumitru-Popescu din Martie 24, 2015, 18:17:26
Am facut pentru problema asta 2 surse, una in care am folosit algoritmul lui Dijkstra "ca la carte", si una in care faceam un fel de bfs - bagam un element in coada, ma duceam la toti vecinii, iar daca distanta noua pana la vecini este mai mica decat distanta veche, reintroduceam vecinul in coada si recalculam. A doua sursa a luat, neasteptat, tot 100 pct. Ba chiar a obtinut timpi mai buni de executie, in medie, decat abordarea clasica cu Dijkstra. Cum e posibil acest lucru, nu ar trebui sa aiba o complexitate mai mare, care trage spre n patrat?  ](*,) ](*,) As aprecia mult daca m-ar ajuta cineva sa inteleg cum sursa aparent mai proasta o depaseste pe cea cu Dijkstra.

Iata cele doua surse si borderourile de evaluare:

1. Dijkstra:
http://www.infoarena.ro/job_detail/1399323 - borderou
http://www.infoarena.ro/job_detail/1399323?action=view-source - sursa

2. BFS:
http://www.infoarena.ro/job_detail/1399062 - borderou
http://www.infoarena.ro/job_detail/1399062?action=view-source - sursa.

Multumesc anticipat  :D :D


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Bucevschi Alexandru din Martie 24, 2015, 20:38:30
Ceea ce faci tu in a doua sursa e Bellman-Ford care are cam aceeasi complexitate cu Dijkstra http://www.infoarena.ro/problema/bellmanford (http://www.infoarena.ro/problema/bellmanford)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Strimbu Alexandru din Martie 26, 2015, 13:57:35
Dijkstra are complexitate O(M*logN), iar Bellman-Ford are O(M*N). Bellman Ford cu coada, asa cum l-ai facut tu, are aceeasi complexitate O(M*N), dar in practica e la fel de bun ca Dijkstra. Practic, niciodata nu o sa faca N*M pasi. Bellman-Ford e util cand ai costuri negative pe muchii, deoarece atunci Dijkstra nu merge.


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Mouse Wireless din Mai 28, 2015, 00:19:44
In "indicatiile" problemei scrie ca o rezolvare cu set va lua doar 80 de puncte dar eu am trimis cu set si am luat 100  :roll:.. si nu m-am chinuit prea mult cu optimizari. Poate ar trebui redusa un pic limita de timp?


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Vlad Dumitru-Popescu din Ianuarie 30, 2016, 23:09:20
Pentru cei ce vor sa inteleaga algoritmul lui Dijkstra si poate nu au inteles din sursa data in explicatii, aici este implementarea mea de 100 de puncte, scrisa clar si explicata prin comentarii. Implementarea foloseste priority_queue.

http://pastebin.com/xTgRuZKn

Sper sa fie de ajutor!  :D :D


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Tatuta Ionut-Catalin din Mai 09, 2016, 10:55:21
eu nu inteleg de ce pe primul test, si anume:

7 9
1 4 2
1 2 1
2 3 3
4 3 1
3 5 2
5 6 5
6 3 1
3 7 2
1 5 9

avem fisierul cu output "corect"

1 3 2 5 10 5

asta insemnand ca distanta minima de la primul nod la al saselea ar fi de 10
totusi mie mi se pare ca distanta mai scurta ar fi prin 1-4,4-3,3-6, cu un cost total de 4



Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Tatuta Ionut-Catalin din Mai 09, 2016, 10:55:40
eu nu inteleg de ce pe primul test, si anume:

7 9
1 4 2
1 2 1
2 3 3
4 3 1
3 5 2
5 6 5
6 3 1
3 7 2
1 5 9

avem fisierul cu output "corect"

1 3 2 5 10 5

asta insemnand ca distanta minima de la primul nod la al saselea ar fi de 10
totusi mie mi se pare ca distanta mai scurta ar fi prin 1-4,4-3,3-6, cu un cost total de 4



Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Tatuta Ionut-Catalin din Mai 09, 2016, 11:25:55
ok, nvm, tocmai am aflat ca graful era orientat  ](*,)


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: boboc vasile din Aprilie 24, 2018, 18:23:23
Poate ma lamureste si pe mine cineva.

Sa luam, spre exemplu testul 1.
Date de intrare:
7 9
1 4 2
1 2 1
2 3 3
4 3 1
3 5 2
5 6 5
6 3 1
3 7 2
1 5 9

Date de iesire:
1 3 2 5 10 5
Daca pana la nodul 3 distanta minima e 3 (de acord), iar intre 3 si 6 exista drum de lungime 1, de ce drumul minim pana la 6 e 10(mie imi da 4)?
Multumesc anticipat!!


Titlul: Răspuns: 009 Algoritmul lui Dijkstra
Scris de: Dicianu Ioan-Alexandru din Aprilie 29, 2019, 17:29:59
@dragon, Graful este orientat. Ai arc de la nodul 6 la nodul 3, nu există arc de la 3 la 6 care să aibă costul 1. Implementarea ta probabil că folosește un graf neorientat. :)