Advertisement
Guest User

Untitled

a guest
Apr 24th, 2017
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.89 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. #include <iomanip>
  5.  
  6. #define Max 150
  7. #define Found 1
  8. #define notFound 0
  9.  
  10. using namespace std;
  11.  
  12. struct Graph {
  13. int sodinh;
  14. int a[Max][Max];
  15. int visited[Max];
  16. int LuuVet[Max];
  17. };
  18.  
  19. struct Queue {
  20. int size;
  21. int a[Max];
  22. };
  23.  
  24. struct Canh
  25. {
  26. int u;//Dinh thu nhat
  27. int v;//Dinh thu hai
  28. int trongso;
  29. };
  30.  
  31. Canh T[Max];
  32.  
  33. void readGraph(string fn, Graph &g);
  34. void printGraph(Graph g);
  35.  
  36. void DFS(int s, Graph &g);
  37. void duyetDFS(int s, int f, Graph &g);
  38.  
  39. void khoiTao(Queue &q);
  40. bool Them(int k, Queue &q);
  41. bool kiemTraRong(Queue q);
  42. bool Lay(int &v, Queue &q);
  43.  
  44. void BFS(int s, Graph &g);
  45. void duyetBFS(int s, int f, Graph &g);
  46.  
  47. bool dfsHamilton(int path[], Graph g, int &count);
  48. int visit(int u, int visited[], int &count, int &flag, int path[], Graph g);
  49. void printHamilton(Graph g, int path[]);
  50.  
  51. void Prim(Graph g);
  52.  
  53. void Kruskal(Graph g, int &nT, Canh T[]);
  54. void khoiTaoMangCanh(Graph g, int &nCanh, Canh DSCanh[]);
  55. void sapXepCanh(int nCanh, Canh DSCanh[], Graph g);
  56. bool coChuTrinh(Graph g, Graph h, int iMin, Canh DSCanh[]);
  57.  
  58. int main()
  59. {
  60. int a,countHamilton;
  61. Graph g;
  62. Canh T[100];
  63. int path[100];
  64. readGraph("test9.txt", g);
  65. printGraph(g);
  66. //dfsHamilton(path, g, countHamilton);
  67. //Prim(g);
  68. Kruskal(g, a, T);
  69. system("pause");
  70. }
  71.  
  72. void readGraph(string fn, Graph &g) {
  73. fstream f;
  74. f.open(fn);
  75. f >> g.sodinh;
  76. for (int i = 0; i < g.sodinh; i++)
  77. for (int j = 0; j < g.sodinh; j++)
  78. f >> g.a[i][j];
  79. f.close();
  80. }
  81.  
  82. void printGraph(Graph g) {
  83. cout << "So dinh la: " << g.sodinh << endl;
  84. for (int i = 0; i < g.sodinh; i++) {
  85. for (int j = 0; j < g.sodinh; j++)
  86. cout << g.a[i][j];
  87. cout << endl;
  88. }
  89. cout << endl;
  90. }
  91.  
  92. //hàm xét từ đỉnh s bất kỳ
  93. void DFS(int s, Graph &g)
  94. {
  95. //Đánh dấu đỉnh s đã suyệt
  96. g.visited[s] = 1;
  97.  
  98. //Tìm xem từ đỉnh s có đỉnh i nào chưa duyệt và nối trực tiếp với s
  99. for (int i = 0; i < g.sodinh; i++)
  100. if (g.visited[i] == 0 && g.a[s][i] != 0)
  101. {
  102. g.LuuVet[i] = s; //Lưu trước đỉnh i là đỉnh s
  103. DFS(i, g);//gọi đệ quy tiến hành xét tiếp
  104. }
  105. }
  106.  
  107. //Hàm tìm đường đi từ đỉnh s đến đỉnh f trong đồ thị g
  108. void duyetDFS(int s, int f, Graph &g)
  109. {
  110. //Khởi tạo giá trị ban đầu, tất cả các địh chư đuợc duyệt và chưa lưu vết
  111. for (int i = 0; i < g.sodinh; i++)
  112. {
  113. g.visited[i] = 0;
  114. g.LuuVet[i] = -1;
  115. }
  116.  
  117. //Gọi hàm DFS
  118. DFS(s, g);
  119.  
  120. if (g.visited[f] == 1)
  121. {
  122. //In ket qua
  123. int j = f;
  124. while (j != s)
  125. {
  126. cout << j+1 << "<---";
  127. j = g.LuuVet[j];
  128. }
  129. cout << s+1;
  130. cout << endl;
  131. }
  132. else
  133. cout << "Khong co duong di tu dinh " << s+1<< " den dinh " << f+1;
  134. cout << endl;
  135. }
  136.  
  137. void khoiTao(Queue &q) {
  138. q.size = 0;
  139. }
  140. bool Them(int k, Queue &q)
  141. {
  142. if (q.size + 1 > Max) return false;
  143. q.a[q.size] = k;
  144. q.size++;
  145. return true;
  146. }
  147. bool kiemTraRong(Queue q)
  148. {
  149. return (q.size == 0);
  150. }
  151. bool Lay(int &v, Queue &q)
  152. {
  153. if (kiemTraRong(q)) return false;
  154. v = q.a[0];
  155. for (int i = 0; i < q.size - 1; i++)
  156. q.a[i] = q.a[i + 1];
  157. q.size--;
  158. return true;
  159. }
  160.  
  161. void BFS(int s, Graph &g)
  162. {
  163. Queue q;
  164. khoiTao(q);
  165. Them(s, q);//Thêm đỉnh s vào q
  166.  
  167. while (!kiemTraRong(q))
  168. {
  169. Lay(s, q);
  170. //Đánh dấu đỉnh s đã suyệt
  171. g.visited[s] = 1;
  172. for (int i = 0; i < g.sodinh; i++)
  173. if (g.visited[i] == 0 && g.a[s][i] != 0)
  174. {
  175. Them(i, q);
  176. g.LuuVet[i] = s;
  177. }
  178. }
  179. }
  180.  
  181. void duyetBFS(int s, int f, Graph &g)
  182. {
  183. //Khởi tạo giá trị ban đầu, tất cả các địh chư đuợc duyệt và chưa lưu vết
  184. for (int i = 0; i < g.sodinh; i++)
  185. {
  186. g.visited[i] = 0;
  187. g.LuuVet[i] = -1;
  188. }
  189.  
  190. //Gọi hàm BFS
  191. BFS(s, g);
  192.  
  193. if (g.visited[f] == 1)
  194. {
  195. //In ket qua
  196. int j = f;
  197. while (j != s)
  198. {
  199. cout << j+1 << "<---";
  200. j = g.LuuVet[j];
  201. }
  202. cout << s+1;
  203. cout << endl;
  204. }
  205. else
  206. cout << "Khong co duong di tu dinh " << s << " den dinh " << f;
  207. cout << endl;
  208. }
  209.  
  210. bool dfsHamilton(int path[], Graph g, int &count)
  211. {
  212. int count;
  213. int start = 0;
  214. int flag = notFound; //2: cho biết ý nghĩa của biến flag
  215. int visited[Max]; //3: cho biết ý nghĩa của mảng visited
  216. for (int i = 0; i < g.sodinh; i++) {
  217. visited[i] = 0;
  218. }
  219. count = 0; //đếm số lượng đỉnh trong chu trình Hamilton đang tìm
  220. path[count] = start;
  221. count++;
  222. visited[start] = 1;
  223. flag = visit(start, visited, count, flag, path, g);
  224. if (flag) return Found; else return notFound;
  225. }
  226.  
  227. int visit(int u, int visited[], int &count, int &flag, int path[], Graph g) {
  228. if (flag == Found) return flag;
  229. for (int v = 0; v < g.sodinh; v++)
  230. if (visited[v] == 0 && g.a[u][v] != 0) {//nếu u kề v, v chưa thăm
  231. visited[v] = 1;
  232. path[count] = v;
  233. count++;
  234. if (count == g.sodinh && g.a[v][path[0]] != 0) //4: cho biết ý nghĩa
  235. flag = Found;
  236. visit(v, visited, count, flag, path, g);
  237. }
  238. if (flag == notFound) {//5: cho biết ý nghĩa của đoạn chtr này
  239. visited[u] = 0; count--;
  240. }
  241. return flag;
  242. }
  243.  
  244. void printHamilton(Graph g, int path[], int &count) {
  245. if (dfsHamilton(path, g, count) == 1) {
  246. cout << "Chu trinh la: ";
  247. for (int i = 0; i < count; i++) cout << path[i] << " ";
  248. cout << endl;
  249. }
  250. else cout << "Do thi khong co chu trinh";
  251. }
  252.  
  253. void Prim(Graph g)
  254. {
  255. //B1: Gán số cạnh của cây khung ban đầu là 0
  256. int nT = 0;
  257. //B2: Khởi tạo nhãn các đỉnh là chưa duyệt (0)
  258. for (int i = 0; i < g.sodinh; i++)
  259. g.visited[i] = 0;
  260.  
  261. //B3: Đánh dấu đỉnh 0 là đã duyệt
  262. g.visited[0] = 1;
  263.  
  264. while (nT < g.sodinh - 1)//nếu đủ n -1 cạnh thì dừng (Tại sao, dựa vào đâu??)
  265. {
  266. Canh canhnhonhat;//dùng để lưu trữ cạnh nhỏ nhất từ một đỉnh đã xét tới đỉnh chưa xét
  267. int min = -1; //Tại sao lấy -1????
  268. for (int i = 0; i < g.sodinh; i++)
  269. if (g.visited[i] == 0) //nếu là đỉnh chưa duyệt. Điều kiện đúng khi j thuộc tập Y hay V\Y
  270. {
  271. for (int j = 0; j < g.sodinh; j++)
  272. if (g.visited[j] == 1 && (g.a[i][j] != 0))
  273. {
  274. if (min == -1 || g.a[i][j] < min)
  275. {
  276. min = g.a[i][j];
  277. canhnhonhat.u = i;
  278. canhnhonhat.v = j;
  279. canhnhonhat.trongso = g.a[i][j];
  280. }
  281. }
  282. }
  283.  
  284. //Thêm cạnh nhỏ nhất vào tập T
  285. T[nT] = canhnhonhat;
  286. nT++;//tăng số cạnh lên 1
  287.  
  288. g.visited[canhnhonhat.u] = 1;//Tại sao????
  289.  
  290. }
  291.  
  292. //Tổng trọng số của cây khung
  293. int sum = 0;
  294. cout << "Cay khung nho nhat cua do thi la: " << endl;
  295. for (int i = 0; i < nT; i++)
  296. {
  297. cout << "(" << T[i].u+1 << ", " << T[i].v+1 << ") ";
  298. sum += T[i].trongso;
  299. }
  300. cout << endl;
  301. cout << "Tong gia tri cua cay la: " << sum << endl;
  302. }
  303.  
  304. void Kruskal(Graph g, int &nT, Canh T[])
  305. {
  306. int nCanh;
  307. Canh DSCanh[100];
  308. Graph h;
  309. for (int i = 0; i < g.sodinh; i++)
  310. for (int j = 0; j < g.sodinh; j++)
  311. h.a[i][j] = 0;
  312. //Khởi tạo danh sách cạnh của đồ thị
  313. khoiTaoMangCanh(g, nCanh, DSCanh);
  314. //Sắp xếp danh sách cạnh tăng dần theo trọng số
  315. sapXepCanh(nCanh, DSCanh, g);
  316.  
  317. //Gán số cạnh của cây khung là 0
  318. nT = 0;
  319.  
  320. int iMin = 0; //chỉ số phần tử cạnh đang xét
  321.  
  322. //Lần lượt đưa các cạnh vào cây khung để không tạo ra chu trình
  323. while (nT < g.sodinh - 1)
  324. {
  325. if (iMin < nCanh)
  326. {
  327. if (coChuTrinh(g, h, iMin, DSCanh) == false)
  328. {
  329. T[nT] = DSCanh[iMin];
  330. cout << endl << T[nT].u << "-" << T[nT].v << "-" << T[nT].trongso;
  331. nT++;
  332. }
  333. iMin++;
  334. }
  335. else
  336. {
  337. break;
  338. }
  339. }
  340. cout << endl;
  341. int sum = 0;
  342. //for (int i = 0; i < nT; i++) {
  343. //cout << "(" << T[i].u + 1 << "," << T[i].v + 1 << ")" << setw(4);
  344. //sum = sum + T[i].trongso;
  345. //}
  346. //cout << endl << "Tong gia tri cua cay khung la " << sum << endl;
  347. }
  348.  
  349. void khoiTaoMangCanh(Graph g, int &nCanh, Canh DSCanh[]) {
  350. nCanh = 0;
  351. int j = 0;
  352. for (int i = 0; i < g.sodinh; i++) {
  353. for (int j=i+1;j<g.sodinh;j++)
  354. if (g.a[i][j] != 0) {
  355. DSCanh[nCanh].trongso = g.a[i][j];
  356. DSCanh[nCanh].u = i;
  357. DSCanh[nCanh].v = j;
  358. nCanh++;
  359. }
  360. }
  361. //for (int i = 0; i < nCanh; i++) cout << DSCanh[i].u + 1 << "-" << DSCanh[i].v + 1 << "-" << DSCanh[i].trongso << setw(4);
  362. }
  363.  
  364. void sapXepCanh(int nCanh, Canh DSCanh[], Graph g) {
  365. bool nhohon = 1;
  366. while (nhohon == 1) {
  367. nhohon = 0;
  368. for (int i = 0; i < nCanh-1; i++)
  369. if (DSCanh[i].trongso > DSCanh[i+1].trongso) {
  370. Canh Temp;
  371. Temp = DSCanh[i];
  372. DSCanh[i] = DSCanh[i + 1];
  373. DSCanh[i + 1] = Temp;
  374. nhohon = 1;
  375. }
  376. }
  377. for (int i = 0; i < nCanh; i++) cout << DSCanh[i].u+1 << "-" << DSCanh[i].v+1 << "-" << DSCanh[i].trongso << setw(4);
  378. }
  379.  
  380. bool coChuTrinh(Graph g, Graph h, int iMin, Canh DSCanh[]) {
  381. int pathx[100],c;
  382. h.a[DSCanh[iMin].u][DSCanh[iMin].v] = 1;
  383. if (dfsHamilton(pathx, h, c)) return true;
  384. return false;
  385. }
  386. //2 = 1 5 = 1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement