Advertisement
bartekltg

doo

Nov 23rd, 2012
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.94 KB | None | 0 0
  1.  
  2. #include <cstdlib>
  3. #include <cstdio>
  4. #include <algorithm>
  5. #include <vector>
  6. #include <queue>
  7. #include <set>
  8.  
  9. const int ROWNIK = 360*3600;
  10.  
  11.  
  12. using namespace std;
  13.  
  14. class ladowanie;
  15.  
  16. class polaczenie
  17. {
  18. public:
  19.     int cel;
  20.     int cena;
  21.     int dlugosc;
  22.     polaczenie(int _cel, int _cena, int _dlugosc) { cel = _cel; cena = _cena; dlugosc = _dlugosc; };
  23.     polaczenie() { cel=0; cena=0; dlugosc=0; };
  24.     ladowanie lec( const ladowanie &skad );
  25. };
  26.  
  27.  
  28.  
  29.  
  30. class miasto
  31. {
  32. public:
  33.     int wspolrzedna;
  34.     vector < polaczenie > polaczenia ;
  35.     miasto(){wspolrzedna=0;}
  36.     miasto(int _wspolrzedna) {wspolrzedna= _wspolrzedna;};
  37.     vector<ladowanie> podrozuj( const ladowanie &start );
  38. };
  39.  
  40.  
  41.  
  42.  
  43.  
  44. class ladowanie //etap wycieczki
  45. {
  46. public:
  47.     int indeks_miasta; //indeks miasta
  48.     int nakrycie; // topologiczne nad S^1 ;)
  49.     int koszt; // jak daleko w bajtotalarach od miasta 1.
  50.     int wspolrzedna;
  51.     ladowanie () { indeks_miasta=0; nakrycie=0; koszt =0;wspolrzedna=0;};
  52.     ladowanie (int m, int wsp) { indeks_miasta=m; nakrycie=0; koszt =0;wspolrzedna=wsp;};
  53. };
  54.  
  55. int przesuniecie(miasto &a, miasto &b , int k)
  56. {
  57.     int roznica = (ROWNIK+ k*b.wspolrzedna - k*a.wspolrzedna) % ROWNIK;
  58.     return roznica*k;
  59. };
  60.  
  61.  
  62. ladowanie polaczenie::lec( const ladowanie &skad )
  63. {
  64.     ladowanie cel_lotu = ladowanie(this->cel, skad.wspolrzedna+this->dlugosc);
  65.     cel_lotu.koszt = skad.koszt + this->cena;
  66.     cel_lotu.nakrycie = skad.nakrycie;
  67.     if (cel_lotu.wspolrzedna<0)
  68.     {
  69.         cel_lotu.nakrycie--;
  70.         cel_lotu.wspolrzedna+=ROWNIK;
  71.     }else if(cel_lotu.wspolrzedna>=ROWNIK)
  72.     {
  73.         cel_lotu.nakrycie++;
  74.         cel_lotu.wspolrzedna-=ROWNIK;
  75.     }
  76.     return cel_lotu;
  77. }
  78.  
  79.  struct porownaj_koszt
  80.  {
  81.      bool operator() (const ladowanie &a,const ladowanie &b)const
  82.             { return (a.koszt > b.koszt); } //kolejka piorytetowa trzyma największy, wiec odwracamy relacje
  83.  };
  84.  
  85.  struct porownaj_indeks
  86.  {
  87.      bool operator () (const ladowanie &a, const ladowanie &b)const
  88.      {   return (a.indeks_miasta< b.indeks_miasta);  }
  89. };
  90.  
  91. vector<ladowanie> miasto::podrozuj( const ladowanie &start )
  92. {
  93.     int n=this->polaczenia.size();
  94.     vector<ladowanie> wyloty(n);
  95.     for (int i=0;i<n;i++)
  96.     {
  97.         wyloty [i] = this->polaczenia[i].lec(start);
  98.     }
  99.     return wyloty;
  100. }
  101.  
  102. int main()
  103. {
  104.     int n,m;
  105.     scanf("%d %d",&n,&m);
  106.  
  107.    
  108.  
  109.     vector <miasto> miasta(n+1);
  110.  
  111.     for (int i=1;i<=n;i++)
  112.     {
  113.         int pozycja;
  114.         scanf("%d",&pozycja);
  115.         miasta[i]=miasto(pozycja);
  116.     }
  117.     for (int i=0;i<m;i++)
  118.     {
  119.         int a,b,x,k;
  120.         scanf("%d %d %d %d", &a,&b,&x,&k);
  121.         int przes = przesuniecie(miasta[a],miasta[b],k);
  122.         miasta[a].polaczenia.push_back(polaczenie(b,x, przes));
  123.         miasta[b].polaczenia.push_back(polaczenie(a,x, -przes));
  124.     }
  125.  
  126.  
  127.     priority_queue<ladowanie, vector<ladowanie>, porownaj_koszt> kolejka;
  128.     kolejka.push(ladowanie(1,miasta[1].wspolrzedna));
  129.  
  130.     priority_queue<int, vector<int>, greater<int> >taniosc; // ;)
  131.  
  132.     set<ladowanie,porownaj_indeks> odwiedzone; //miasta (x) kakrycie zminimalizowane
  133.  
  134.     while (!kolejka.empty())
  135.     {
  136.         ladowanie L = kolejka.top();
  137.         kolejka.pop();
  138.        
  139.         set<ladowanie,porownaj_indeks>::iterator it;
  140.         it = odwiedzone.find(L);
  141.  
  142.         if ((it->indeks_miasta == L.indeks_miasta)&&(it!=odwiedzone.end()) && (odwiedzone.size()>0) ) // w tym mieście już lądowaliśmy
  143.         {
  144.             if (it->nakrycie!=L.nakrycie)//znaleźliśmy cykl, zamykający się w tym mieście!
  145.             {//wrzucamy propozycję na stosik i nie podróżujemy dalej z tego lądowania.
  146.                 taniosc.push(L.koszt+it->koszt);   
  147.                 odwiedzone.insert(L);
  148.             };// else to samo nakrycie-> to samo lądowanie, ale z konstrukcji alg.D gorsze. Olewamy
  149.         }
  150.         else
  151.         { //nie ma miasta na liscie.
  152.             odwiedzone.insert(L);
  153.             vector<ladowanie> nowe_loty = miasta[L.indeks_miasta].podrozuj(L);
  154.             //Dodajemy wszystko, co stad wylatuje
  155.             for (int i=0;i<nowe_loty.size(); i++)  
  156.             {
  157.                 kolejka.push(nowe_loty[i]);
  158.             }
  159.         }
  160.  
  161.     }//Dijkstra skonczył;
  162.  
  163.     if (taniosc.empty())
  164.     {
  165.         printf("-1\n");
  166.     }
  167.     else
  168.     {
  169.         printf("%d\n",taniosc.top());
  170.     }
  171.  
  172.  
  173.    
  174.     return 0;
  175. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement