Advertisement
cmiN

adj-mat

May 9th, 2012
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.22 KB | None | 0 0
  1. #include <iostream>
  2. using namespace std;
  3.  
  4.  
  5. const int N = 128;
  6. int mat[N][N]; // matricea de adiacenta - folosita in mai multe probleme
  7. int nr; // numarul de linii si coloane
  8.  
  9.  
  10. void fill_mat()
  11. {
  12.     /// Functie pentru completarea matricei de adiacenta.
  13.     cout << "Dimensiune: ";
  14.     cin >> nr;
  15.     for (int i = 1; i <= nr; ++i) {
  16.         for (int j = 1; j <= nr; ++j) {
  17.             cout << i << "-" << j << ": ";
  18.             cin >> mat[i][j];
  19.         }
  20.     }
  21. }
  22.  
  23.  
  24. bool f8()
  25. {
  26.     // mai folosim functia asta si in alta problema
  27.     // de aceea returneaza ceva :)
  28.     // graf neorientat -> mat[a][b] == mat[b][a]
  29.     // verificam deasupra diagonalei principale (nu e nevoie neaparat si sub)
  30.     for (int i = 1; i <= nr; ++i) {
  31.         for (int j = i + 1; j <= nr; ++j)
  32.         if (mat[i][j] != mat[j][i]) {
  33.             // avem muchie de la un nod la altul dar nu si invers
  34.             // deci graful este orientat
  35.             cout << "Nu" << endl;
  36.             return 0;
  37.         }
  38.     }
  39.     cout << "Da" << endl;
  40.     return 1;
  41. }
  42.  
  43.  
  44. void f11()
  45. {
  46.     // aici sigur trebuie sa citim si matricea de adiacenta
  47.     // sa stim de ce muchii dispunem
  48.     int vec1[N], vec2[N];
  49.     int len1, len2;
  50.     cout << "Dimensiune v1: ";
  51.     cin >> len1;
  52.     cout << "Dimensiune v2: ";
  53.     cin >> len2;
  54.     cout << "Elemente v1: ";
  55.     for (int i = 0; i < len1; ++i) cin >> vec1[i];
  56.     cout << "Elemente v2: ";
  57.     for (int i = 0; i < len2; ++i) cin >> vec2[i];
  58.     /* graf bipartit complet: de la fiecare nod sa existe muchie la fiecare alt nod
  59.        si pentru fiecare muchie un nod sa se gaseasca in multimea v1 si celalalt in v2
  60.        mai exact de la fiecare nod din v1 sa existe o muchie la toate celelalte noduri din v2
  61.        si sa nu existe muchii de la vreun nod din v1 la un nod tot in v1
  62.     */
  63.     for (int i = 0; i < len1; ++i) {
  64.         int nod = vec1[i];
  65.         // verificam sa nu existe muchie in interior
  66.         for (int j = 0; j < len1; ++j) {
  67.             if (mat[nod][vec1[j]] || mat[vec1[j]][nod]) {
  68.                 // exista
  69.                 cout << "Nu" << endl;
  70.                 return;
  71.             }
  72.         }
  73.         // totul ok pentru nodul i mai ramane sa verificam
  74.         // existenta muchiilor de la el la toate celelalte din v2
  75.         for (int j = 0; j < len2; ++j) {
  76.             // doar in cazul bun (atunci cand exista drum si inainte
  77.             // si inapoi de la nod din v1 la nod din v2) expresia va fi 0/falsa
  78.             if (!(mat[nod][vec2[j]] && mat[vec2[j]][nod])) {
  79.                 cout << "Nu" << endl;
  80.                 return;
  81.             }
  82.         }
  83.     }
  84.     cout << "Da" << endl;
  85. }
  86.  
  87.  
  88. void dfs(int nod, bool vazut[])
  89. {
  90.     // marcam ca vizitat nodul curent si apoi vizitam toti ceilalti vecini
  91.     // asta daca nu a fost deja vizitat acest nod
  92.     if (vazut[nod]) return; // iesim
  93.     // nevizitat, vizitam
  94.     vazut[nod] = 1;
  95.     for (int i = 1; i <= nr; ++i) {
  96.         if (mat[nod][i]) dfs(i, vazut);
  97.     }
  98. }
  99.  
  100.  
  101. bool f21()
  102. {
  103.     // si pe asta o mai folosim
  104.     // un graf neorientat este conex daca din oricare nod se poate ajunge in oricare nod
  105.     // este de ajuns sa facem o parcurgere dintr-un nod la toti ceilalti vecini
  106.     // si daca raman noduri nevizitate inseamna ca nu s-a putut ajunge la ele
  107.     // deci graful nu-i conex
  108.     bool vazut[N]; // 0-nevizitat 1-vizitat
  109.     for (int i = 0; i < N; ++i) vazut[i] = 0;
  110.     // vam parcurge graful in adancime
  111.     dfs(1, vazut); // mereu exista un prim nod
  112.     // acum daca a ramas vreun nod nevizitat clar ca nu e conex
  113.     for (int i = 1; i <= nr; ++i) if (!vazut[i]) {
  114.         cout << "Nu" << endl;
  115.         return 0;
  116.     }
  117.     cout << "Da" << endl;
  118.     return 1;
  119. }
  120.  
  121.  
  122. bool check(int from, int nod, bool vazut[])
  123. {
  124.     // functia returneaza 1 daca a gasit ciclu
  125.     // si 0 in caz contrar (atunci cand e ok pentru un arbore)
  126.     if (vazut[nod]) return 1;
  127.     for (int i = 1; i <= nr; ++i) {
  128.         if (mat[nod][i] && i != from) {
  129.             // daca exista drum de la nod la i si
  130.             // nodul in care ne vom deplasa difera de nodul din care am venit
  131.             // atunci vizitam, asta pentru ca sa nu ne pacalim singuri
  132.             // ca ar fi ciclu fiindca nodul din care venim intotdeauna e vizitat
  133.             return check(nod, i, vazut);
  134.         }
  135.     }
  136. }
  137.  
  138.  
  139. void f22()
  140. {
  141.     // arbore = graf neorientat conex aciclic
  142.     if (!(f8() && f21())) {
  143.         // nu este neorientat conex
  144.         cout << "Nu" << endl;
  145.         return;
  146.     }
  147.     // acum verificam sa nu aiba cicluri
  148.     // procedam similar ca si la vizita (dfs) numai ca functia va avea alta conotatie
  149.     // acum vom tine minte din ce nod am venit ca sa nu ne intoarcem in acesta
  150.     // si in timpul parcurgerii vom verifica daca a mai fost vizitat deja un nod
  151.     // daca a mai fost vizitat e clar ca s-a putut ajunge in el si din alta parte
  152.     // o alta parte decat traseul curent deci avem un ciclu, circuit inchis
  153.     // deci nu se mai numeste arbore
  154.     bool vazut[N];
  155.     for (int i = 0; i < N; ++i) vazut[i] = 0;
  156.     if (check(0, 1, vazut)) {
  157.         cout << "Nu" << endl;
  158.         return;
  159.     }
  160.     cout << "Da" << endl;
  161. }
  162.  
  163.  
  164. int main()
  165. {
  166.     fill_mat();
  167.     f8();
  168.     f11();
  169.     f21();
  170.     f22();
  171.     return 0;
  172. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement