Advertisement
Guest User

Untitled

a guest
Feb 20th, 2017
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.26 KB | None | 0 0
  1. // Maksymalne skojarzenia
  2. // Data: 26.10.2014
  3. // (C)2014 mgr Jerzy Wałaszek
  4. //---------------------------
  5.  
  6. #include <iostream>
  7.  
  8. using namespace std;
  9.  
  10. const int MAXINT = 2147483647;
  11.  
  12. // Definicja typu elementów listy
  13. //-------------------------------
  14. struct slistEl
  15. {
  16. slistEl * next;
  17. int data;
  18. };
  19.  
  20. // Definicja typu obiektowego queue
  21. //---------------------------------
  22. class queue
  23. {
  24. private:
  25. slistEl * head;
  26. slistEl * tail;
  27.  
  28. public:
  29. queue(); // konstruktor
  30. ~queue(); // destruktor
  31. bool empty(void);
  32. int front(void);
  33. void push(int v);
  34. void pop(void);
  35. };
  36.  
  37. //---------------------
  38. // Metody obiektu queue
  39. //---------------------
  40.  
  41. // Konstruktor - tworzy pustą listę
  42. //---------------------------------
  43. queue::queue()
  44. {
  45. head = tail = NULL;
  46. }
  47.  
  48. // Destruktor - usuwa listę z pamięci
  49. //-----------------------------------
  50. queue::~queue()
  51. {
  52. while(head) pop();
  53. }
  54.  
  55. // Sprawdza, czy kolejka jest pusta
  56. //---------------------------------
  57. bool queue::empty(void)
  58. {
  59. return !head;
  60. }
  61.  
  62. // Zwraca początek kolejki.
  63. // Wartość specjalna to -MAXINT
  64. //-----------------------------
  65. int queue::front(void)
  66. {
  67. if(head) return head->data;
  68. else return -MAXINT;
  69. }
  70.  
  71. // Zapisuje do kolejki
  72. //--------------------
  73. void queue::push(int v)
  74. {
  75. slistEl * p = new slistEl;
  76. p->next = NULL;
  77. p->data = v;
  78. if(tail) tail->next = p;
  79. else head = p;
  80. tail = p;
  81. }
  82.  
  83. // Usuwa z kolejki
  84. //----------------
  85. void queue::pop(void)
  86. {
  87. if(head)
  88. {
  89. slistEl * p = head;
  90. head = head->next;
  91. if(!head) tail = NULL;
  92. delete p;
  93. }
  94. }
  95.  
  96. //---------------
  97. // Program główny
  98. //---------------
  99.  
  100. queue Q; // Kolejka
  101. int *Color; // Tablica kolorów wierzchołków
  102. slistEl **graf; // Tablica list sąsiedztwa
  103. int **C; // Macierz przepustowości
  104. int **F; // Macierz przepływów netto
  105. int *P; // Tablica poprzedników
  106. int *CFP; // Tablica przepustowości rezydualnych
  107. int n,m,fmax,cp,v,u,i,j; // Zmienne proste algorytmu
  108. bool esc; // Do wychodzenia z zagnieżdżonych pętli
  109. slistEl *pr, *rr; // Wskaźniki elementów listy
  110.  
  111. // Funkcja zwraca true, jeśli graf jest dwudzielny.
  112. // Ustala kolory wierzchołków w tablicy Color
  113. //------------------------------------------------
  114. bool isBipartite()
  115. {
  116. for(int i = 0; i < n; i++) // Przechodzimy przez kolejne wierzchołki
  117. if(!Color[i]) // Szukamy wierzchołka szarego
  118. {
  119. Color[i] = 1; // Wierzchołek startowy kolorujemy na czerwono
  120. Q.push(i); // i umieszczamy w kolejce
  121.  
  122. while(!Q.empty()) // Przejście BFS
  123. {
  124. v = Q.front(); // Pobieramy wierzchołek z kolejki
  125. Q.pop(); // Pobrany wierzchołek usuwamy z kolejki
  126. for(pr = graf[v]; pr; pr = pr->next) // Przeglądamy sąsiadów wierzchołka v
  127. {
  128. u = pr->data; // pobieramy z listy sąsiedztwa numer sąsiada
  129. if(Color[u] == Color[v]) return false;
  130.  
  131. if(!Color[u]) // Jeśli wierzchołek nie jest odwiedzony,
  132. {
  133. Color[u] = -Color[v]; // kolorujemy go na kolor przeciwny
  134. Q.push(u); // i umieszczamy w kolejce
  135. }
  136. }
  137. }
  138. }
  139.  
  140. return true;
  141. }
  142.  
  143. int main()
  144. {
  145. // Ze standardowego wejścia odczytujemy
  146. // n - liczbę wierzchołków w grafie sieci
  147. // m - liczbę krawędzi
  148.  
  149. cin >> n >> m;
  150.  
  151. // Tworzymy dane dynamiczne
  152.  
  153. Color = new int [n]; // Tablica kolorów wierzchołków
  154. graf = new slistEl * [n]; // Tablica list sąsiedztwa
  155. for(i = 0; i < n; i++)
  156. {
  157. graf[i] = NULL;
  158. Color[i] = 0;
  159. }
  160.  
  161. C = new int * [n+2]; // Macierz przepustowości krawędzi
  162. F = new int * [n+2]; // Macierz przepływów netto
  163. for(i = 0; i <= n + 1; i++)
  164. {
  165. C[i] = new int [n+2];
  166. F[i] = new int [n+2];
  167. for(j = 0; j <= n + 1; j++)
  168. {
  169. C[i][j] = 0;
  170. F[i][j] = 0;
  171. }
  172. }
  173.  
  174. P = new int [n+2]; // Tablica poprzedników
  175. CFP = new int [n+2]; // Tablica przepustowości rezydualnych
  176.  
  177. // Odczytujemy definicje krawędzi i dodajemy je do list sąsiedztwa
  178.  
  179. for(i = 0; i < m; i++)
  180. {
  181. cin >> v >> u;
  182. pr = new slistEl;
  183. pr->data = u;
  184. pr->next = graf[v];
  185. graf[v] = pr;
  186.  
  187. pr = new slistEl;
  188. pr->data = v;
  189. pr->next = graf[u];
  190. graf[u] = pr;
  191. }
  192.  
  193. if(isBipartite())
  194. {
  195. // Ustawiamy macierz przepustowości
  196. for(i = 0; i < n; i++)
  197. if(Color[i] == -1)
  198. {
  199. for(pr = graf[i]; pr; pr = pr -> next) // Przeglądamy listę sąsiadów wierzchołka niebieskiego
  200. C[i][pr->data] = 1; // Przepustowość krawędzi do wierzchołka czerwonego
  201. C[n][i] = 1; // Przepustowość krawędzi od źródła
  202. }
  203. else C[i][n+1] = 1; // Przepustowość krawędzi do ujścia
  204.  
  205. //**************************************************
  206. //** Tutaj rozpoczyna się algorytm Edmondsa-Karpa **
  207. //**************************************************
  208.  
  209. fmax = 0;
  210.  
  211. while(true)
  212. {
  213. for(i = 0; i <= n + 1; i++) P[i] = -1;
  214.  
  215. P[n] = -2;
  216. CFP[n] = MAXINT;
  217.  
  218. while(!Q.empty()) Q.pop();
  219. Q.push(n);
  220.  
  221. esc = false;
  222.  
  223. while(!Q.empty())
  224. {
  225. v = Q.front(); Q.pop();
  226.  
  227. for(u = 0; u <= n + 1; u++)
  228. {
  229. cp = C[v][u] - F[v][u];
  230. if(cp && (P[u] == -1))
  231. {
  232. P[u] = v;
  233. if(CFP[v] > cp) CFP[u] = cp; else CFP[u] = CFP[v];
  234. if(u == n+1)
  235. {
  236. fmax += CFP[n+1];
  237. i = u;
  238. while(i != n)
  239. {
  240. v = P[i];
  241. F[v][i] += CFP[n+1];
  242. F[i][v] -= CFP[n+1];
  243. i = v;
  244. }
  245. esc = true; break;
  246. }
  247. Q.push(u);
  248. }
  249. }
  250. if(esc) break;
  251. }
  252. if(!esc) break;
  253. }
  254.  
  255. // Wyświetlamy wyniki
  256.  
  257. cout << endl
  258. << "NUMBER OF MATCHES = " << fmax
  259. << endl;
  260. if(fmax > 0)
  261. for(v = 0; v < n; v++)
  262. for(u = 0; u < n; u++)
  263. if((C[v][u] == 1) && (F[v][u] == 1))
  264. cout << v << " - " << u << endl;
  265. }
  266. else cout << endl << "NOT A BIBARTITE GRAPH" << endl;
  267.  
  268. cout << endl;
  269.  
  270. // Usuwamy dane dynamiczne
  271.  
  272. delete [] Color; // Tablica kolorów wierzchołków
  273.  
  274. for(i = 0; i < n; i++)
  275. {
  276. pr = graf[i];
  277. while(pr)
  278. {
  279. rr = pr;
  280. pr = pr->next;
  281. delete rr;
  282. }
  283. }
  284.  
  285. delete [] graf; // Tablica list sąsiedztwa
  286.  
  287. for(i = 0; i <= n + 1; i++)
  288. {
  289. delete [] C[i];
  290. delete [] F[i];
  291. }
  292. delete [] C; // Macierz przepustowości krawędzi
  293. delete [] F; // Macierz przepływów netto
  294.  
  295. delete [] P; // Tablica poprzedników
  296. delete [] CFP; // Tablica przepustowości rezydualnych
  297.  
  298. return 0;
  299. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement