Ciao!
Il tuo codice va in TLE perché la tua implementazione di Dijkstra non controlla se un nodo è già stato visitato prima di controllare i suoi vicini.
Esempio
Nell’esempio
5 5
0 1 1
0 2 5
1 3 10
2 3 5
3 4 10
il tuo codice itererà due volte sui vicini del nodo 3. Questo è perché il nodo 3 verrà inserito due volte nella priority_queue, una prima volta mentre si sta visitando il nodo 1, e nuovamente mentre si sta visitando il nodo 2 dato che, passando da esso, il percorso è più breve.
Questo tuttavia fa sì che il idx_u sia uguale a 3 per due iterazioni del ciclo while, cosa superflua visto che la prima iterazione è sufficiente a trovare potenziali percorsi minimi passanti dal nodo 3.
Come spiegato qui nel primo paragrafo questo porta la complessità da O(Nlog(M)+Mlog(M)) a O(NM) che, viste le assunzioni del problema, spiega il perché dei TLE.
Per risolvere dovrebbe essere sufficiente cambiare le prime linee del ciclo while a:
int idx_u = q.top().second;
long long dist_u=q.top().first;
q.pop();
if(D[idx_u]!=dist_u){
continue;
}
Questo perché se dist_u è diverso da D[idx_u], questo vuol dire che, dopo che la coppia {dist_u, idx_u} è stata inserita nella priority_queue, è stato trovato un percorso più breve per arrivare al nodo idx_u e, dato che la priority_queue mette in cima le coppie con la distanza minore, la coppia contenente il percorso più breve è già stata considerata. Di conseguenza, il nodo idx_u è già stato visitato ed i suoi vicini controllati in cerca di potenziali nuovi percorsi minimi