Buongiorno, avrei bisogno di aiuto per il problema interruttori di Algobadge. Il codice da risultati sbagliati (1 corretto su 24) e alcuni output non vengono prodotti.
Grazie in anticipo.
Il mio codice:
#include <iostream>
#include <fstream>
#include <utility>
#include <vector>
using namespace std;
vector<vector<bool>> connectMatrix;
vector<int> nodeWeight;
void controllaVicini(int startNode, int N) {
for (int vicino = 0; vicino < N; vicino++) {
if (!connectMatrix[startNode][vicino]);
else if (nodeWeight[vicino] == 0 || nodeWeight[startNode] + 1 < nodeWeight[vicino]) {
nodeWeight[vicino] = nodeWeight[startNode] + 1;
controllaVicini(vicino, N);
}
}
}
void solve(int t) {
int N, A, B;
cin >> N >> A >> B;
vector<int> Z(A), X(B), Y(B);
for (int i = 0; i < A; i++) {
cin >> Z[i];
}
for (int i = 0; i < B; i++) {
cin >> X[i] >> Y[i];
}
// start
// riempimento della matrice di adiacenza
for (int i = 0; i < N; i++) {
vector<bool> mBuffer;
for (int i = 0; i < N; i++) {
mBuffer.push_back(false);
}
connectMatrix.push_back(mBuffer);
}
for (int i = 0; i < B; i++) {
connectMatrix[X[i]][Y[i]] = true;
connectMatrix[Y[i]][X[i]] = true;
}
// riempimento nodeWeight
for (int i = 0; i < N; i++) {
nodeWeight.push_back(0);
}
for (int i = 0; i < A; i++) {
nodeWeight[Z[i]] = 1;
}
// ogni lampadina di tipo 1 controlla vicini
for (int i = 0; i < A; i++) {
controllaVicini(Z[i], N);
}
// trova num e idx
int idx; // memorizza qui l'indice della lampadina
int num = 0; // memorizza qui il numero di interruttori
for (int i = 0; i < N; i++) {
if (nodeWeight[i] > num) {
num = nodeWeight[i];
idx = i;
}
}
// end
cout << "Case #" << t << ": " << idx << " " << num << "\n";
}
int main() {
// se preferisci leggere e scrivere da file
// ti basta decommentare le seguenti due righe:
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int T;
cin >> T;
for (int t = 1; t <= T; t++) {
solve(t);
}
return 0;
}
Grazie! Ho capito il mio errore. Ho provato a usare una lista di adiacenza e l’ho dichiarata dentro solve(), nodeWeight invece non sapevo come aggiungerla tra i parametri di controllaVicini() perchè non sono sicuro se modificando i suoi valori all’interno della funzione li modifica anche fuori da essa, perciò l’ho comunque dichiarata come variabile globale e l’ho riempita con zeri all’inizio di ogni test. Provando il codice funziona (ha prodotto l’output a 9 casi ed erano tutti corretti) ma probabilmente è ancora troppo lento (erano 9 casi su 24).
Per caso avete qualche consiglio?
Il mio codice:
#include <iostream>
#include <fstream>
#include <utility>
#include <vector>
using namespace std;
vector<int> nodeWeight;
void controllaVicini(int node, vector<vector<int>> list) {
for (int i = 0; i < list[node].size(); i++) {
int endNode = list[node][i];
if (nodeWeight[endNode] == 0 || nodeWeight[node] + 1 < nodeWeight[endNode]) {
nodeWeight[endNode] = nodeWeight[node] + 1;
controllaVicini(endNode, list);
}
}
}
void solve(int t) {
int N, A, B;
cin >> N >> A >> B;
vector<int> Z(A), X(B), Y(B);
for (int i = 0; i < A; i++) {
cin >> Z[i];
}
for (int i = 0; i < B; i++) {
cin >> X[i] >> Y[i];
}
// aggiungi codice...
vector<vector<int>> connectList(N);
nodeWeight.resize(N);
// inizializzare connectList
for (int i = 0; i < B; i++) {
connectList[X[i]].push_back(Y[i]);
connectList[Y[i]].push_back(X[i]);
}
// inizializzare nodeWeight (interruttori di tipo 1 hanno valore iniziali 1)
for (int i = 0; i < N; i++)
nodeWeight[i] = 0;
for (int i = 0; i < A; i++)
nodeWeight[Z[i]] = 1;
// controllo di tutti i nodi a partire dagli interruttori di tipo 1
for (int i = 0; i < A; i++)
controllaVicini(Z[i], connectList);
// trovare idx e num
int idx; // memorizza qui l'indice della lampadina
int num = 0; // memorizza qui il numero di interruttori
for (int i = 0; i < N; i++) {
if (nodeWeight[i] > num) {
num = nodeWeight[i];
idx = i;
}
}
// end
cout << "Case #" << t << ": " << idx << " " << num << "\n";
}
int main() {
// se preferisci leggere e scrivere da file
// ti basta decommentare le seguenti due righe:
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int T;
cin >> T;
for (int t = 1; t <= T; t++) {
solve(t);
}
return 0;
}
Per passare nodeWeight come parametro a controllaVicini in modo che venga comunque modificato all’interno della funzione puoi passarlo per riferimento e non per valore (che è quello che succede di default), ma anche la tua soluzione non dovrebbe dare problemi su nodeWeight.
Per quanto riguarda la lentezza, passare list per riferimento dovrebbe bastare per velocizzare il codice a sufficienza.
Riassumendo: puoi passare per riferimento nodeWeight come parametro a controllaVicini per modificarlo all’interno della funzione e, soprattutto, passando list per riferimento eviti di crearne una copia ad ogni chiamata di controllaVicini velocizzando significativamente il tuo codice.