Advertisement
Tucancitto

Lab3 - Pb1

Apr 8th, 2021 (edited)
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.00 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <vector>
  4. #include <queue>
  5. #include <algorithm>
  6. using namespace std;
  7.  
  8. struct GRAF
  9. {
  10.     vector<vector<int>> ListaAdiac;
  11.  
  12.     void citire(string fisier)
  13.     {
  14.         ifstream fin(fisier);
  15.         if (!fin)
  16.         {
  17.             cout << "Eroare. \n";
  18.             return;
  19.         }
  20.  
  21.         int nrNoduri;
  22.         fin >> nrNoduri;
  23.         ListaAdiac.resize(nrNoduri);
  24.  
  25.         for (int index = 0; index < nrNoduri; ++index)
  26.         {
  27.             int nrSucc;
  28.             fin >> nrSucc;
  29.             for (int index2 = 0; index2 < nrSucc; ++index2)
  30.             {
  31.                 int succ;
  32.                 fin >> succ;
  33.                 ListaAdiac[index].push_back(succ);
  34.             }
  35.         }
  36.  
  37.         fin.close();
  38.     }
  39.  
  40.     void afisareListe()
  41.     {
  42.         for (int index = 0; index < ListaAdiac.size(); ++index)
  43.         {
  44.             cout << "L[" << index << "]: ";
  45.             for (int index2 = 0; index2 < ListaAdiac[index].size(); ++index2)
  46.                 cout << ListaAdiac[index][index2] << ' ';
  47.             cout << endl;
  48.         }
  49.         cout << endl;
  50.     }
  51.  
  52.     GRAF& operator =(GRAF G)
  53.     {
  54.         G.ListaAdiac.resize(ListaAdiac.size());
  55.         for (int index = 0; index < ListaAdiac.size(); ++index)
  56.             for (int index2 = 0; index2 < ListaAdiac[index].size(); ++index2)
  57.                 G.ListaAdiac[index].push_back(G.ListaAdiac[index][index2]);
  58.  
  59.         return G;
  60.     }
  61.  
  62.     bool verifSucc(int nod, int deCautat)
  63.     {
  64.         int p = 0, u = ListaAdiac[nod].size() - 1;
  65.         while (p <= u)
  66.         {
  67.             int mij = (p + u) / 2;
  68.             if (ListaAdiac[nod][mij] == deCautat)
  69.                 return 1;
  70.             else
  71.                 if (ListaAdiac[nod][mij] < deCautat)
  72.                     p = mij + 1;
  73.                 else
  74.                     u = mij - 1;
  75.         }
  76.         return 0;
  77.     }
  78.  
  79.     void formareNeorientat(GRAF& G)
  80.     {
  81.         for (int index = 0; index < ListaAdiac.size(); ++index)
  82.             for (int index2 = 0; index2 < ListaAdiac[index].size(); ++index2)
  83.             {
  84.                 int succ = ListaAdiac[index][index2];
  85.                 if (!verifSucc(succ, index))
  86.                     G.ListaAdiac[succ].push_back(index);
  87.             }
  88.  
  89.         for (int index = 0; index < ListaAdiac.size(); ++index)
  90.             sort(G.ListaAdiac[index].begin(), G.ListaAdiac[index].end());
  91.     }
  92.  
  93.     int neviz(vector<bool> viz)
  94.     {
  95.         for (int index = 0; index < ListaAdiac.size(); ++index)
  96.             if (viz[index] == 0)
  97.                 return index;
  98.         return -1;
  99.     }
  100.  
  101.     template<typename T>
  102.     void atr(vector<T>& vect, int dim, int val)
  103.     {
  104.         for (int index = 0; index < dim; ++index)
  105.             vect[index] = val;
  106.     }
  107.  
  108.     vector<int> BFS(int start, int dest, vector<bool>& viz)
  109.     {
  110.         vector<int> pred, comp;
  111.         queue<int> coada;
  112.  
  113.         if (dest != -1)
  114.         {
  115.             pred.resize(ListaAdiac.size());
  116.             atr(pred, pred.size(), -1);
  117.         }
  118.         else
  119.             comp.push_back(start);
  120.  
  121.         viz[start] = 1;
  122.         coada.push(start);
  123.  
  124.         while (!coada.empty())
  125.         {
  126.             int cap = coada.front();
  127.             coada.pop();
  128.             for (int index = 0; index < ListaAdiac[cap].size(); ++index)
  129.             {
  130.                 int succ = ListaAdiac[cap][index];
  131.                 if (viz[succ] == 0)
  132.                 {
  133.                     viz[succ] = 1;
  134.                     coada.push(succ);
  135.  
  136.                     if (dest != -1)
  137.                     {
  138.                         pred[succ] = cap;
  139.                         if (succ == dest)
  140.                             return pred;
  141.                     }
  142.                     else
  143.                         comp.push_back(succ);
  144.                 }
  145.             }
  146.         }
  147.  
  148.         return comp;
  149.     }
  150.  
  151.     vector<int> determinareCale(int start, int dest)
  152.     {
  153.         vector<int> pred, cale;
  154.         vector<bool> viz;
  155.         pred.resize(ListaAdiac.size());
  156.         viz.resize(ListaAdiac.size());
  157.  
  158.         atr(viz, viz.size(), 0);
  159.  
  160.         pred = BFS(start, dest, viz);
  161.  
  162.         if (!pred.empty())
  163.         {
  164.             int nod = dest;
  165.             cale.push_back(nod);
  166.             while (pred[nod] != -1)
  167.             {
  168.                 cale.push_back(pred[nod]);
  169.                 nod = pred[nod];
  170.             }
  171.         }
  172.         return cale;
  173.     }
  174.  
  175.     void afisareCale(int start, int dest, vector<int> cale)
  176.     {
  177.         cout << "Calea este: {";
  178.         for (int index = cale.size() - 1; index > 0; --index)
  179.             if (verifSucc(cale[index], cale[index - 1]))
  180.                 cout << "(" << cale[index] << ", " << cale[index - 1] << "), ";
  181.             else
  182.                 cout << "(" << cale[index - 1] << ", " << cale[index] << "), ";
  183.         cout << "\b\b} \n\n";
  184.     }
  185.  
  186.     void drum(int start, int dest)
  187.     {
  188.         vector<int> cale;
  189.         cale.resize(determinareCale(start, dest).size());
  190.         cale = determinareCale(start, dest);
  191.         if (!cale.empty())
  192.         {
  193.             cout << "Exista drum de la " << start << " la " << dest << ". \n";
  194.             afisareCale(start, dest, cale);
  195.         }
  196.         else
  197.             cout << "Nu exista drum de la " << start << " la " << dest << ". \n\n";
  198.     }
  199.  
  200.     void lant(int start, int dest, GRAF GN)
  201.     {
  202.         vector<int> cale;
  203.         cale.resize(GN.determinareCale(start, dest).size());
  204.         cale = GN.determinareCale(start, dest);
  205.  
  206.         if (!cale.empty())
  207.         {
  208.             cout << "Exista lant de la " << start << " la " << dest << ". \n";
  209.             afisareCale(start, dest, cale);
  210.         }
  211.         else
  212.             cout << "Nu exista lant de la " << start << " la " << dest << ". \n\n";
  213.     }
  214.  
  215.     void compConexe()
  216.     {
  217.         vector<bool> viz;
  218.         viz.resize(ListaAdiac.size());
  219.         atr(viz, viz.size(), 0);
  220.  
  221.         int nrCompConexe = 0, nod = neviz(viz);
  222.         do
  223.         {
  224.             vector<int> comp = BFS(nod, -1, viz);
  225.             sort(comp.begin(), comp.end());
  226.  
  227.             cout << "Componenta conexa cu numarul " << ++nrCompConexe << " contine varfurile {";
  228.             for (auto vf : comp)
  229.                 cout << vf << ", ";
  230.             cout << "\b\b} \n";
  231.  
  232.             nod = neviz(viz);
  233.         } while (nod != -1);
  234.  
  235.         cout << "Numar total de componente conexe: " << nrCompConexe << endl;
  236.     }
  237.  
  238.     void clear()
  239.     {
  240.         for (int index = 0; index < ListaAdiac.size(); ++index)
  241.         {
  242.             ListaAdiac[index].clear();
  243.             ListaAdiac[index].shrink_to_fit();
  244.         }
  245.  
  246.         ListaAdiac.clear();
  247.         ListaAdiac.shrink_to_fit();
  248.     }
  249. };
  250.  
  251. int main()
  252. {
  253.     GRAF GO;
  254.     GO.citire("liste.in");
  255.  
  256.     GRAF GN = GO;
  257.     GN.formareNeorientat(GN);
  258.  
  259.     cout << "Listele de adiacenta ale grafului orientat: \n";
  260.     GO.afisareListe();
  261.  
  262.     // a)
  263.     int start, dest;
  264.     cout << "Introduceti nodul de start si cel de destinatie pt a determina un drum (daca exista): ";
  265.     cin >> start >> dest;
  266.     if (start != dest)
  267.         GO.drum(start, dest);
  268.     else
  269.         cout << "Varfurile introduse sunt identice. \n\n";
  270.  
  271.     // b)
  272.     cout << "Introduceti nodul de start si cel de destinatie pt a determina un lant (daca exista): ";
  273.     cin >> start >> dest;
  274.     if (start != dest)
  275.         GO.lant(start, dest, GN);
  276.     else
  277.         cout << "Varfurile introduse sunt identice. \n\n";
  278.  
  279.     // c)
  280.     cout << "Componentele conexe: \n";
  281.     GN.compConexe();
  282.  
  283.     GO.clear();
  284.     GN.clear();
  285.  
  286.     return 0;
  287. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement