Grafi - 2 PON Olimpiadi di Informatica Prof. Reho Gabriella 1 Algoritmo per l’ordinamento topologico di un grafo • Un semplice algoritmo per l’ordinamento topologica di un grafo è fa uso della visita DFS inserendo ogni nodo visitato in una pila da cui poi stampare i valori altermine della visita: PON Olimpiadi di Informatica Prof. Reho Gabriella 2 void Topological_sort(lista_nodi G[],int s,int visito[]){ cout<<"\nSto visitando il nodo "<<s; visito[s]=1; //Per ogni nodo adiacente al nodo u cioè nella lista di adiacenza di u for (int j=0;j<G[s].size();j++){ int v=G[s][j]; if (visito[v]==0) { visito[v]=1; DFS(G,v,visito); pila.push(v); } } } int main(){ fill_n(visitati,N,0); for(int i=0;i<N;i++) if (!visitati[i]) Topological_sort(G,i,visitati); while(!pila.empty()){ cout<<pila.top()<<“ “; pila.pop(); } } PON Olimpiadi di Informatica Prof. Reho Gabriella 3 Esercizio • Selezioni regionali 2007 - Torero Escamillo (torero) • Difficoltà D = 2 (tempo limite 1 sec). • Descrizione del problema Il celebre torero Escamillo deve indossare il proprio costume prima di entrare nell'arena. Egli è costretto a rispettare un dato numero di precedenze, indossando certi indumenti prima di altri, mentre alcuni indumenti possono essere liberamente indossati in un ordine qualsiasi. Per esempio, le "medias" (calze) vanno indossate prima delle "zapatillas" (scarpe), ma non vi è alcun vincolo sull'ordine con cui indossare la "chaquetilla" (giacca) e la "montera" (cappello). Il costume di Escamillo è particolarmente raffinato ed elaborato e si compone di N indumenti. Sfortunatamente, Carmen non ha ancora consegnato uno degli N indumenti necessari alla vestizione di Escamillo. Aiutalo a vestirsi il più possibile, calcolando il massimo numero di indumenti che può indossare in attesa che Carmen gli consegni l'indumento mancante. PON Olimpiadi di Informatica Prof. Reho Gabriella 4 • • • Dati di input Il file input.txt contiene nella prima riga una tripla di interi, separati da uno spazio: l'intero positivo N che indica il numero di indumenti per la vestizione di Escamillo, dove gli indumenti sono numerati da 1 a N; l'intero positivo M che indica il numero di precedenze tra coppie di indumenti da rispettare durante la vestizione; l'intero Q, compreso tra 1 e N, che indica l'indumento non ancora consegnato da Carmen. Ognuna delle successive M righe contiene una coppia di interi, compresi tra 1 e N, separati da uno spazio. Tale coppia di interi I e J rappresenta la precedenza in cui l'indumento numero I deve essere indossato prima dell'indumento numero J. Assunzioni: 1 < N < 100000 1 < M < 100000 1≤Q≤N Dati di output Il file output.txt è composto da una riga contenente un solo intero, che rappresenta il massimo numero di indumenti che Escamillo riesce a indossare in attesa dell'indumento Q che Carmen deve ancora consegnargli. PON Olimpiadi di Informatica Prof. Reho Gabriella 5 Cammini minimi in un grafo • Uno dei problemi che si possono applicare ad una struttura di tipo grafo è il calcolo del cammino minimo che collega due nodi del grafo. Uno tra gli algoritmi che calcolano tale cammino con una complessità ottima è l’algoritmo di DiJkstra. Il cammino minimo tra il nodo 0 e il nodo 4 è lungo 3. Se applicassimo la visita in ampiezza BFS, calcolerebbe il cammino lungo 6, il che non è corretto. PON Olimpiadi di Informatica Prof. Reho Gabriella 6 Algoritmo di Dijkstra • L’algoritmo di Dijkstra visita i nodi nel grafo, in maniera simile a una ricerca in ampiezza o in profondità. In ogni istante, l’insieme N dei nodi del grafo è diviso in tre parti: l’insieme dei nodi visitati V, l’insieme dei nodi di frontiera F, che sono successori dei nodi visitati, e i nodi sconosciuti, che sono ancora da esaminare. • Per ogni nodo z, l’algoritmo tiene traccia di un valore dz, inizialmente posto uguale a ∞ che rappresenta la distanza di ciascun nodo dal nodo sorgente, e di un nodo uz,inizialmente indefinito che rappresenta il nodo predecessore di ciascun nodo appartenente al cammino minimo che collegherà il nodo sorgente alla destinazione. PON Olimpiadi di Informatica Prof. Reho Gabriella 7 • L’algoritmo che cerca il cammino minimo dal nodo x al nodo y, parte con V =Ф , F={x}, dx=0 e prosegue finché y non viene visitato, o finché F =Ф: in questo caso, y non è raggiungibile da x lungo un arco orientato. Se usciamo solo nel secondo caso, alla fine dell’algoritmo dz contiene, per ogni nodo z, il peso di un cammino minimo da x a z; inoltre, il vettore u permette di ricostruire l’albero dei cammini minimi con origine in x. PON Olimpiadi di Informatica Prof. Reho Gabriella 8 Esempio: calcoliamo il cammino minimo da 0 a 4 V={0} F={1,2,4} L’algoritmo aggiorna il vettore delle distanze con le distanze dei nodi di frontiera dal nodo 0. d[1]=1 d[2]=2 d[4]=6 PON Olimpiadi di Informatica Prof. Reho Gabriella 9 Continua… L’algoritmo di Dijkstra cerca tra i nodi del grafo che stiamo visitando quello a distanza minima dalla sorgente. In questo caso il nodo prescelto è il nodo 1 che dista da 0, 1. La regola che si segue è quindi: Quindi si inserisce nell’insieme V il nodo 1 V={0,1} e si prosegue aggiornando il vettore delle distanze con le distanze dei nodi appartenenti alla frontiera di 1. F={3,4} d[3]=d[1]+1=2 d[4]=min{d[4] ,d[1]+3}=4 L’algoritmo prosegue cercando nuovamente nel vettore delle distanze quello non ancora visitato e a distanza minima dalla sorgente… PON Olimpiadi di Informatica Prof. Reho Gabriella 10 Continua… Si sceglierà il nodo 2 che però non comporterà alcuna modifica nel vettore delle distanze in quanto per il nodo appartenente alla frontiera di 2 che è 3, conosciamo già un cammino di peso minimo migliore di quello che passerebbe per il nodo 2. Visitiamo ora il nodo 3, aggiornando nuovamente d4 e u4: d[4]=3 u[4]=3 V={0,1,2,3} A questo punto visitiamo il nodo 4 che è la nostra destinazione finale e l’algoritmo termina. Il vettore u ci rappresenta il cammino minimo leggendolo a partire dalla destinazione fino alla sorgente: 4 - u[4]=3 - u[3]=1 – u[1]=0 PON Olimpiadi di Informatica Prof. Reho Gabriella 11 int cammino(int x, int y ) { //Calcolo il cammino minimo da x ad y int i, j, m; for (i=0;i<N; i++) { d[i]=MAXINT; u[i]=N+1; vis[i]=0; } d[x]=0; for( ; ; ) { for (m=MAXINT, i=0; i<N; i++) //Trovo il nodo a distanza minima da x if(!vis[i] && (d[i]<=m)) m=d[j=i]; vis[j]=1; //sto visitando il nodo j if (j==y || m==MAXINT) //esco dal ciclo se ho raggiunto la destinazione break; //oppure se la destinazione non è raggiungibile for (i=0; i<N; i++) if (G[j][i] && (d[i]> d[j]+G[j][i])) { d[i]= d[j]+G[j][i]; u[i]=j; } } return j; //restituisco l'ultimo nodo visitato se è y ho trovato un cammino minimo } PON Olimpiadi di Informatica Prof. Reho Gabriella 12 • • • • • • • Distanze (DIST) Livello di difficoltà D=8 Antonio e’ in viaggio, e ha una tabella di distanze tra citta’. Su di essa, purtroppo, non compare la distanza tra la sua citta’ di partenza e quella di arrivo, per raggiungere la quale bisogna passare per altre citta’ intermedie. Dovete aiutare Antonio a trovare la distanza relativa al percorso piu’ breve tra la citta’ di partenza e quella di arrivo desumibile dalla tabella. File di input Il file input.txt e’ costituito da una prima riga nella quale sono indicati, separati da un carattere spazio, il numero totale di citta’ in tabella N e il numero di distanze mutue tra due citta’ D. Seguono D righe, ciascuna delle quali contiene gli identificatori numerici delle due citta’ e la loro mutua distanza, separati da un carattere spazio. File di output Il programma, dopo aver letto il file di input, deve calcolare la distanza minima tra la citta’ di partenza e quella di arrivo, e scriverla su un file di nome output.txt. Più precisamente, il file output.txt deve essere costituito da una sola riga, contenente un numero intero che rappresenta la distanza piu’ breve tra la citta’ di partenza e quella di arrivo. PON Olimpiadi di Informatica Prof. Reho Gabriella 13 Assunzioni Il file di input non contiene altri caratteri oltre a quelli precisati. Il numero N di citta’ e' in ogni caso inferiore a 1000, ed il numero di distanze D inferiore a 10000. Gli identificatori delle citta’ sono interi compresi tra 1 e N. La citta’ di partenza e la destinazione sono sempre associate agli identificatori 1 e 2, rispettivamente. Importante! L'esecuzione del programma deve terminare entro 30 secondi. PON Olimpiadi di Informatica Prof. Reho Gabriella 14