Cammino minimo 0/100

Di recente ho provato a risolvere il problema cammino minimo.
Ho provato esattamente in tre modi. Per prima cosa ho provato implementando Belman Ford, ma l’algoritmo era troppo lento. Dopo di che sono passato a Djikstra, notando che implementando Djikstra, il codice aveva ugualmente dei testcase errati. Dopo un analisi del problema sono arrivato a questo argomento, che dà ugualmente 0/100. Cosa sto sbagliando?

#include <vector>
#include<utility> 

using namespace std;

struct struttura{
	vector<pair<int, int>> collegamenti; 
	int entrata = 0; 
	bool passato = false; 
	bool collegatoazero = false; 
}; 

void mincammino(int N, int M, vector<int> X, vector<int> Y, vector<int> P, vector<int> &D) {
	vector<struttura> nodo(N);
	pair<int, int> a; 
	nodo[0].collegatoazero = true; 
	for(int i = 0; i < M; i++){
		nodo[Y[i]].entrata++; 
		a.first = Y[i]; 
		a.second = P[i];  
		nodo[X[i]].collegamenti.push_back(a); 
		if(nodo[X[i]].collegatoazero) nodo[Y[i]].collegatoazero; 
	}
	
	int posizionetop = 0; 
	D[0] = 0; 
	while(posizionetop < N){
		
		for(int i = 0; i < N; i++){
			if(nodo[i].entrata == 0){
				for(int l = 0; l < nodo[i].collegamenti.size(); l++){
					//cout << i  << " : i " << D[i] << " : COSTO I " << nodo[i].collegamenti[l].first << ": PEKO PAIN " << D[i] + nodo[i].collegamenti[l].second << " : COSTO"<< endl;
					nodo[nodo[i].collegamenti[l].first].entrata--;
					if(nodo[i].collegatoazero && (nodo[nodo[i].collegamenti[l].first].passato == false || D[nodo[i].collegamenti[l].first] > D[i] + nodo[i].collegamenti[l].second)){
						D[nodo[i].collegamenti[l].first]= D[i] + nodo[i].collegamenti[l].second; 
						nodo[nodo[i].collegamenti[l].first].passato = true; 
						nodo[nodo[i].collegamenti[l].first].collegatoazero = true; 
					}
				} 
				nodo[i].entrata = -1; 
				break; 
			}
		}
		posizionetop++; 
	}
	/*for(int i = 0; i < N; i++){
		cout << nodo[i].passato << endl; 
	}*/
	D[0] = 0; 
	for(int i = 1; i < N; i++) if(nodo[i].passato == false) D[i] = -1; 
}

Con Dijkstra funziona, riguardati come l’hai implementato.

perfetto, vedrò di implementarlo nuovamente

ti ringrazio, funziona, avevo sbagliato un passaggio nel codice, solo che ero stanco e non me n’ero accorto

una domanda ho implementato Djikstra in questo modo, cosa sbaglio?

#include <vector>

#include<utility>

#include<algorithm>

#include<climits>

#include<queue>

#define INT_MAX 2147483647

using namespace std;

struct struttura{

    priority_queue<pair<int, int>> collegamenti;

    int lunghezza = INT_MAX;

};

vector<struttura> nodi;

void Djikstra(int index, int N, vector<int> &D){

    while(!nodi[index].collegamenti.empty()){

       

        //cout << nodi[index].collegamenti.top().second << " ";

        if(D[nodi[index].collegamenti.top().second] > D[index] + nodi[index].collegamenti.top().first * -1){

           

            D[nodi[index].collegamenti.top().second] = D[index] + nodi[index].collegamenti.top().first * -1;

            Djikstra(nodi[index].collegamenti.top().second, N, D);

        }

        nodi[index].collegamenti.pop();

    }

}

void mincammino(int N, int M, vector<int> X, vector<int> Y, vector<int> P, vector<int> &D) {

    nodi.resize(N);

    D.resize(N);

    pair<int, int> input;

    int i;

    for(i = 0; i < N; i++) D[i] = INT_MAX;

    for(i = 0; i < M; i++){

               

        input.second = Y[i];

        input.first = -1 * P[i];

        nodi[X[i]].collegamenti.push(input);

    }

   

    i = 0;

    D[0] = 0;

    //cout << " Arrivo qua " << endl;

    Djikstra(i, N, D);

    for(i = 0; i < N; i++){

        if(D[i] == INT_MAX) D[i] = -1;

    }

}

Prova con questo input:
5 7
0 1 1
0 2 1
1 3 1
2 1 1
3 2 1
3 4 1
2 4 1

va bene fra poco provo, grazie dell’aiuto

ho provato a prendere 100/100 con quest’implementazione di Djikstra, ma non funziona ugualmente, prendo 20/100:

#include <vector>

#include<utility>

#include<algorithm>

#include<climits>

#include<queue>

#define INT_MAX 2147483647

using namespace std;

struct archi{

    int fine;

    int costo;

};

void mincammino(int N, int M, vector<int> X, vector<int> Y, vector<int> P, vector<int> &D) {

    vector<archi> lista[N];

     

    D.resize(N);

    for(int i = 0; i < M; i++){

        archi in;

        in.fine = Y[i];

        in.costo = P[i];

        lista[X[i]].push_back(in);

        D[in.fine] = INT_MAX;

        D[X[i]] = INT_MAX;

    }

    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;

    pq.push(make_pair(0, 0));  

    D[0] = 0;

    while(!pq.empty()){

        int nodo = pq.top().second;

        pq.pop();

        for(archi pross : lista[nodo]){

            if(D[pross.fine] > D[nodo] + pross.costo){

                D[pross.fine] = D[nodo] + pross.costo;

                pq.push(make_pair(D[pross.fine], pross.fine));

            }  

        }

    }

    for(int i = 0; i < N; i++){

        if(D[i] == INT_MAX) D[i] = -1;

    }

   

}

mincammino da 20/100 a tutti. Ho riprovato la mia soluzione che faceva 100/100 prima e ora fa solamente 20/100

Io ho appena provato a sottoporre nuovamente la mia soluzione e prende 100

Il task è stato aggiornato, sono stati aggiunti nuovi subtask e alcuni testcase sono stati modificati pertanto la tua soluzione potrebbe prendere un punteggio diverso.

scusatemi, ma il mio codice è un classicissimo dijkstra, non vedo per quale motivo non dovrebbe prendere punteggio pieno. Sbaglia completamente il 3 subtask…

#include <bits/stdc++.h>

using namespace std;

struct arco {
	int fine;
	int peso;
};

void mincammino(int N, int M, vector<int> X, vector<int> Y, vector<int> P, vector<int> &D) {
	vector<arco> list[N];
	D.resize(N);
	// Build adjacency list
	for (int i = 0; i < M; i++) {
		arco tmp;
		tmp.fine = Y[i];
		tmp.peso = P[i];
		list[X[i]].push_back(tmp);
		D[X[i]] = -1;
		D[tmp.fine] = -1;
	}
	priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
	pq.push(make_pair(0, 0));
	D[0] = 0;
	while (!pq.empty()) {
		int nodo = pq.top().second;
		pq.pop();
		for (arco next: list[nodo]) {
			if (D[nodo] + next.peso < D[next.fine] || D[next.fine] == -1) {
				D[next.fine] = D[nodo] + next.peso;
				pq.push(make_pair(D[next.fine], next.fine));
			}
		}
	}
}

Inizializza il vettore D[] in questo modo :

for(int i=0; i<N;  i++) D[i] = INT_MAX;

altrimenti qualche distanza non viene inizializzata correttamente.
la tua implementazione dell’algoritmo di Dijkstra salta la distanza in cima alla pq, pertanto devi considerare la distanza dist = pq.top().first e confrontarla con con i nodi adiacenti della lista.

Che babbo che sono. Ci tengo a precisare che questa era una svista e tutte le mie altre implementazioni di dijkstra erano corrette.

:clown_face:

scherzavo, non funziona ancora…

Ok ora funziona… Mi ero dimenticato di inizializzarlo correttamente…