Advertisement
Guest User

Task footing 2

a guest
Apr 30th, 2015
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.54 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <cstdio>
  4. #include <queue>
  5. #include <climits>
  6. #include <algorithm>
  7. #define MAXN 1005
  8. using namespace std;
  9.  
  10. typedef pair<int,int> ii;
  11. typedef vector<ii> vi;
  12. vi G[MAXN];
  13. int N, M, dist[MAXN], prec[MAXN], minimo=INT_MAX;
  14. bool precU[MAXN], vis[MAXN];
  15.  
  16. int prossimoNodo(){ //per i grafi non connessi, trova il prossimo nodo non ancora visitato
  17.     int i;
  18.     for(i=1; i<=N && vis[i]; i++);
  19.     return i;
  20. }
  21.  
  22. int main(){
  23.     freopen("input.txt", "r", stdin);
  24.     freopen("output.txt", "w", stdout);
  25.  
  26.     cin >> N >> M;
  27.     for(int i=0, u, v, w; i<M; i++){
  28.         cin >> u >> v >> w;
  29.         G[u].push_back( make_pair(w, v) );
  30.         G[v].push_back( make_pair(w, u) );
  31.     }
  32.    
  33.     priority_queue< ii, vi, greater<ii> > Q;
  34.     fill_n(dist, N+1, INT_MAX);
  35.     fill_n(prec, N+1, N);
  36.     dist[0]=prec[0]=0;
  37.     int nd;
  38.     while((nd=prossimoNodo())<=N){ //trova il prossimo nodo da cui far partire Dijkstra
  39.         dist[nd] = 0; //distanza iniziale a 0
  40.         Q.push( make_pair(0, nd) ); //inserisco il nodo di partenza nell'heap
  41.         prec[nd] = 0; //precedente iniziale a 0
  42.         while(!Q.empty()){
  43.             int u = Q.top().second; Q.pop(); //prendo il nodo da visitare
  44.             if(vis[u]) continue; //se l'ho già visitato salto al prossimo
  45.            
  46.             for(int i=0; i<G[u].size(); i++){ //vedo i nodi connessi ad "u"
  47.                 int v = G[u][i].second, w = G[u][i].first;
  48.                 if( vis[v] && v!=prec[u]){ //se ce n'è uno che è già visitato ma non è il predecessore, vedo se può essere un ciclo minimo
  49.                    
  50.                     //Trovo il predecessore comune
  51.                     fill_n(precU, N+1, false);
  52.                     int p = prec[u], d;
  53.                     while(p>0){
  54.                         precU[p]=true;
  55.                         p = prec[p];
  56.                     }
  57.                     p = prec[v];
  58.                     while(p>0 && !precU[p])
  59.                         p = prec[p];
  60.                     //ora il predecessore comune sarà "p"
  61.                     if(p==0) p=nd;
  62.                      //la lunghezza del ciclo sarà la DistanzaDaPadU + DistanzaDaPaV + ArcoDaUaV
  63.                     d = dist[u]-dist[p] + dist[v]-dist[p] + w;
  64.                     minimo = min(d, minimo);
  65.                 }
  66.    
  67.                 if( w+dist[u] < dist[v]){ //Classico controllo di Dijkstra
  68.                     dist[v] = w+dist[u];
  69.                     prec[v] = u;
  70.                     Q.push( make_pair(dist[v], v) );
  71.                 }
  72.             }
  73.    
  74.             vis[u] = true; //segno il nodo come visitato
  75.         }
  76.     }
  77.    
  78.     cout << minimo << "\n";
  79.     return 0;
  80. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement