1. Trang chủ
  2. » Công Nghệ Thông Tin

Code Lý thuyết Đồ Thị (Danh sách cung Ma trận)

10 11 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Code Lý Thuyết Đồ Thị (Danh Sách Cung Ma Trận)
Định dạng
Số trang 10
Dung lượng 126,91 KB

Nội dung

Code cho các bài tập Lí thuyết đồ thị về Danh sách cung, Ma trận đỉnhcung đỉnhđỉnh duyệt chiều rộng thì lấy cái bên phải cùng sang xét 8 duyệt chiều sâu thì xét cái đầu tiên bên trái sang bằng ngôn ngữ C các hàm add edge adjacent

Trang 1

1 Code LTDT Tuần 5

2 Danh sách cung

3 Ma trận kề

4 Ma trận đỉnh-cung (dạng chuyển đồi)

5 Ma trận đỉnh-đỉnh (dạng chuyển đồi)

6 Đọc đồ thị từ tập tin

7 tuần 4 duyệt chiều rộng thì lấy cái bên phải cùng sang xét

8 duyệt chiều sâu thì xét cái đầu tiên bên trái sang

9

-

-10

-

-11

-

-12

-

-13 #############################################THEO DANH SACH CUNG################################################################################## 14 !!!Cấu trúc khai báo của 1 Ctr Danh sach Cung: 15 $$Code: 16 #include <stdio.h> 17 #define MAX_M 500 18 //Cấu trúc Edge lưu dữ liệu của 1 cung 19 typedef struct { 20 int u, v; 21 } Edge; 22 //Khai báo cấu trúc dữ liệu Graph 23 typedef struct { 24 int n, m; 25 Edge edges[MAX_M]; 26 } Graph; 27 28 29 30 !!!!!Đọc dữ liệu trong tập tin dt.txt(Hàm này nằm trong hàm MAIN) 31 //Đọc số đỉnh và số cung & khởi tạo đồ thị 32 FILE* file = fopen("dt.txt", "r"); 33 //freopen("dt.txt", "r", stdin); 34 35 !!!!==> sau đó đổi scanf thành fscanf(file,"? %d",&) 36 !!!!==> xong r fclose(file); de dong file xong moi tới hàm để in ra màn hình 37

-

-38

-

-39

-

-40

-

-41

-

-42 1 Hàm init_graph có số đỉnh bằng n và số cung bằng 0 ( PP Danh sách cung): 43 $$CODE: 44 void init_graph(Graph *pG, int n){ 45 pG->n=n; 46 pG->m=0; 47 } 48

-

-49 2 Hàm add_edge() (Hàm chung nhớ tùy vào đề bớt các điều kiện): 50

-51 Cơ bản chỉ cần điều kiện(trùng được , uv và vu phân biệt): 52 $$CODE: 53 54 void add_edge(Graph *pG, int u, int v) {

55 if (u>0 && u<=pG->n && v>0 && v<=pG->n) {

56 // Thêm cung (u, v) vào danh sách cung của đồ thị

57 pG->edges[pG->m].u = u;

58 pG->edges[pG->m].v = v;

Trang 2

59 pG->m++;

60 }

61 } 62

-63 Nâng cao nếu uv có rồi không thêm vào nữa và các tham số đều hợp lệ (nếu không hợp lệ thêm điều kiện vào if của hàm void) Có hướng: 64 $$CODE: 65 66 void add_edge(Graph *pG, int u, int v) { 67 for (int i = 0; i < pG->m; i++) 68 if (pG->edges[i].u == u && pG->edges[i].v == v) 69 return; 70 pG->edges[pG->m].u = u; 71 pG->edges[pG->m].v = v; 72 73 pG->m++; 74 } 75

-76 Nâng cao nếu cung (u, v) hoặc cung (v, u) đã có trong đồ thị rồi thì bỏ qua, không thêm vào nữa(không cho (1,1) luôn) Vô hướng: 77 void add_edge(Graph *pG, int u, int v) { 78 if (u == v) 79 return; 80 for (int i = 0; i < pG->m; i++) 81 if ((pG->edges[i].u == u && pG->edges[i].v == v) || 82 (pG->edges[i].u == v && pG->edges[i].v == u) || u==v) 83 return; 84 pG->edges[pG->m].u = u; 85 pG->edges[pG->m].v = v; 86 pG->m++; 87 } 88

-

-89

-

-90

-

-91 92 3.Hàm adjacent(Graph *pG, int u, int v) để kiểm tra đỉnh u có kề với đỉnh v không theo mẫu (prototype): 93 $$CODE: 94 95 int adjacent(Graph *pG, int u, int v) { 96 int i; 97 for (i = 0; i < pG->m; i++) 98 if ((pG->edges[i].u == u && pG->edges[i].v == v) || 99 (pG->edges[i].u == v && pG->edges[i].v == u)) 100 return 1; 101 return 0; 102 } 103 104

-

-105

-

-106

-

-107

108 4 Hàm degree(Graph *pG,int u) Đếm bậc của đỉnh u của đồ thị bất kỳ:

109 $$CODE:

110 int degree(Graph *pG, int u) {

111 int e, deg_u = 0;

112 //Duyệt qua từng cung 0, 1, 2, …, m - 1

113 for (e = 0; e < pG->m; e++) {

114 //Nếu cung có dạng (u, -)

115 if (pG->edges[e].u == u)

117 //Nếu cung có dạng (-, u)

118 if (pG->edges[e].v == u)

Trang 3

119 deg_u++;

120 }

121 122 return deg_u; 123 } 124 Trong ham main: 125 for (int u = 1; u <= n; u++){ 126 printf("deg(%d) = %d\n", u, degree(&pG, u)); 127 }

128 return 0; // nam ngoai ham for 129 130 131

-

-132

-

-133

-

-134 !!!!!!!!5 //Đọc m cung và thêm vào đồ thị( Bo Tro trong ham Main) 135 !!!!!!!!!rong Hàm Main: 136 int e; 137 for (e = 0; e < m; e++) { 138 scanf("%d%d", &u, &v); ||nếu có đọc file nhớ đồi thành fscanf(file,"",&);|| 139 add_edge(&G, u, v); 140 }

141 142

-

-143

-

-144

-

-145 -####################################################THEO DANH SACH

CUNG############################################################ -146

-

-147

-

-148

-

-149 150 151 152 -##đồ thị vô hướng và in các đỉnh kề của các đỉnh ra màn hình.Biểu diễn đồ thị bằng phương pháp "Danh sách

cung".(neighbours(2))#### -

-153 ## 154 Ham in cac dinh ke cua dinh ra man hinh !!trong main!!! (cho đồ thị vô hướng!!!!!!!!) 155 ###neighbours##### 156 for (int u = 1; u <= n; u++) { 157 printf("neighbours(%d) = ", u); 158 for (int v = 1; v <= n; v++) 159 if (adjacent(&pG, u, v)) 160 printf("%d ", v); 161 printf("\n"); 162 }

163 164 165 return 0; 166 167

-

-168 !! cho đồ thị !!!có hướng!!! thì cái hàm adjacent bỏ cái điều kiện u=v && v=u sau || là

done hàm neighbours vẫn giử nguyên

169 int adjacent(Graph *pG,int u, int v){

170 int i;

171 for(i=0;i<pG->m;i++){

Trang 4

172 if((pG->edges[i].u==u && pG->edges[i].v==v)){

173 return 1;

174 }

175 }return 0; 176 } 177 178 -MA TRAN

KEEEEEEEEEEEEEE -179 180 khai bao MA TRAN KE 181 #include <stdio.h> 182 #define MAX_N 100 183 184 typedef struct { 185 int n, m; 186 int A[MAX_N][MAX_N]; 187 } Graph; 188 #####Hàm init_graph của ma trận kề ( đơn đồ thị vô hướng hoặc đồ thị vô hướng có thể chứa đa cung đa khuyên) 189 void init_graph(Graph *pG, int n){ 190 pG->n=n; 191 pG->m=0; 192 for(int u=1;u<=n;u++){ 193 for(int v=1;v<=n;v++){ 194 pG->A[u][v] = 0; 195 196 }

197 }

198 }

199 200 #### Hàm add_edge của ma trận kề ( đơn đồ thị vô hướng hoặc đồ thị vô hướng có thể chứa đa cung đa khuyên) cứ vô hướng là sử dụng 201 202 void add_edge(Graph *pG,int u,int v){ 203 pG->A[u][v] += 1; 204 if(u != v){ 205 pG->A[v][u] += 1; 206 }

207 pG->m++; 208 }

209

-

-210

-

-211 #######MA TRẬN KỀ đồ thị có hướng đa cung đa khuyên 212 #######chỉ cần thay đổi hàm add_edge không cần if cứ có hướng là sdung hàm này 213 void add_edge(Graph *pG, int u, int v) { 214 pG->A[u][v] += 1; 215 pG->m++; 216 }

217 218

-

-219 ##Hàm In ma trận kề ra man hình 220 printf("Ma tran ke:\n"); 221 for (int u = 1; u <= n; u++) { 222 for (int v = 1; v <= n; v++) 223 printf("%d ", pG.A[u][v]); 224 printf("\n"); 225 }

226 227 return 0; 228 229 -Các hàm tính bậc của đỉnh trong Ma trận kề các loại đồ

thị -

-230

231 * #####hàm Degree "Ma trận kề" dùng để lưu trữ các đồ thị vô hướng (có thể chứa đa

cung và chứa khuyên)

Trang 5

232 int degree(Graph *pG,int u){

233 int v, deg_u=0;

234 for(v=1; v<= pG->n ; v++){

235 deg_u += pG->A[u][v];

236 }

237 return deg_u += pG->A[u][u]; 238 }

239 240

-241 242 * #####hàm Degree "Ma trận kề" dùng để lưu trữ các đồ thị có hướng (có thể chứa đa cung và chứa khuyên) 243 int degree(Graph *pG,int u){ 244 int v, deg_u=0; 245 for(v=1; v<= pG->n ; v++){ 246 deg_u += pG->A[u][v] + pG->A[v][u]; 247 }

248 return deg_u; 249 }

250

-251 252 253 * #####Hàm indegree "Ma trận kề" dùng để lưu trữ các đồ thị có hướng (có thể chứa đa cung và chứa khuyên) 254 int indegree(Graph *pG, int u){ 255 int v, deg_u=0; 256 for(v = 1;v<= pG->n; v++){ 257 deg_u += pG->A[v][u]; 258 }

259 return deg_u; 260 }

261

-262 263 * ####Hàm outdegree "Ma trận kề" dùng để lưu trữ các đồ thị có hướng (có thể chứa đa cung và chứa khuyên) Giống hàm degree vô hướng but return deg_u 264 int outdegree(Graph *pG,int u){ 265 int v, deg_u=0; 266 for(v=1; v<= pG->n ; v++){ 267 deg_u += pG->A[u][v]; 268 }

269 return deg_u; 270 }

271 272 * ##### Hàm neighbours in ra trong ma trận kề vô hướng giống dsach cung thay đổi ngay if còn có hướng thì đổi điều kiện trong add_edge 273 for (int u = 1; u <= n; u++) { 274 printf("neighbours(%d) = ", u); 275 for (int v = 1; v <= n; v++) 276 if (pG.A[u][v]) 277 printf("%d ", v); 278 printf("\n"); 279 }

280 281 282 return 0; 283

-

-284

-

-285

-

-286

287 #### Dạng chuyển đổi

288

289 **** Từ Ma trận kề in ra các các cung kề dạng bài này không cần hàm init với hàm add_edge

290

Trang 6

291 **Hàm khai báo:

292 #include <stdio.h>

293 #define MAX_N 100

294

295 typedef struct {

297 int A[MAX_N][MAX_N];

298 } Graph;

299

300 int main() {

301 Graph pG;

302 int n, a;

303

304 //Đọc số đỉnh và gán cho G.n

305 scanf("%d", &n);

306 pG.n = n;

307 **sau đó

308 //Đọc ma trận kề và gán giá trị vào G.A

309 for (int u = 1; u <= n; u++) {

310 for (int v = 1; v <= n; v++) {

311 scanf("%d", &a);

312 pG.A[u][v] = a;

313 }

314 }

315 **### Hàm in ra nè có điều kiện khi u v (U<=v) (Đồ thị có hướng) 316 **//Liệt kê các cung của G theo thứ tự u <= v sài chung cho các dạng chuyển dồi từ ma trận in ra mỗi cung trên 1 dòng theo mẫu: u v (u≤v) 317 318 for (int u = 1; u <= n; u++) { 319 for (int v = u; v <= n; v++) { tùy chỉnh dòng này 320 for (int k = 0; k < pG.A[u][v]; k++) 321 printf("%d %d\n", u, v); 322 }

323 }

324 return 0; 325 **### Hàm in ra nè 0 có điều kiện khi u v chỉ cần sửa dòng for thứ 2 thành v = 1 là ok vẫn là ma trận kề in ra các cung (Đồ thị vô hướng) 326 327 328

-

-329 ### hàm in ra danh sách kề (In ra n dòng, mỗi dòng tương ứng với một danh sách kề.) của ĐỒ THỊ VÔ HƯỚNG giống hàm in của đồ thị vô hướng for 2 v=1 chỉ sửa dòng for thứ 3 in ra "v" và dòng for bự in "0\n" nhớ return 0; ngoài hàm 330 (In ra n dòng, mỗi dòng tương ứng với danh sách kề của 1 đỉnh.) 331 //G.A[u][v] cho biết số cung đi từ u đến v 332 for (int u = 1; u <= n; u++) { 333 for (int v = 1; v <= n; v++) { 334 for (int k = 0; k < pG.A[u][v]; k++){ 335 printf("%d ", v); 336 }

337 }

338 printf("0\n"); 339 }

340 return 0; 341 ### hàm In ra n dòng, mỗi dòng tương ứng với danh sách kề của 1 đỉnh giống hàm trên 342 343

-

-344

-

-345 Viết chương trình bằng ngôn ngữ C cho phép người nhập vào danh sách kề của các đỉnh

trong một đồ thị vô hướng và in ma trận kề của nó màn hình

346 Dạng nhập dsach kề in ra ma trận( không khai báo a trong hàm main)

347

348 ####Hàm Chung:

349 #include <stdio.h>

350 #define MAX_N 100

Trang 7

351

352 * typedef struct {

354 int A[MAX_N][MAX_N];

355 }Graph;

356

357 * void init_graph(Graph *pG, int n) {

358 pG->n = n;

359

360 for (int u = 1; u <= n; u++)

361 for (int v = 1; v <= n; v++)

362 pG->A[u][v] = 0;

363 }

364

-365 * void add_edge(Graph *pG, int u, int v) { 366 pG->A[u][v] += 1; 367 }

368

-369 * int main() { 370 Graph pG; 371 int n; 372 scanf("%d", &n); 373 pG.n = n; 374 **//Đọc các danh sách kề 375 for (int u = 1; u <= n; u++) { 376 int v; 377 while (1) { 378 scanf("%d", &v); 379 if (v == 0) 380 break; 381 add_edge(&pG, u, v); 382 } của hàm while 383 } ngoặc này của hàm for 384 #*# hàm in ra ma trận kề sử dụng cho đồ thị vô hướng và có hướng luôn sài chung 385 for(int u=1;u<=n;u++){ 386 for(int v=1;v<=n;v++){ 387 printf("%d ",pG.A[u][v]); 388 }

389 printf("\n"); 390 }

391 return 0; 392 393

-

-394

-

-395 Ma Trận Đỉnh-Cung 396 ### Viết hàm add_edge(Graph* pG, int e, int x, int y) để thêm cung e = (x, y) vào đồ thị pG theo mẫu (prototype) Vô Hướng Không chứa khuyên 397 398 void add_edge(Graph* pG, int e, int x, int y) { 399 if (x >= 0 && x < pG->n && y >= 0 && y < pG->n) { 400 if (pG->A[x][e] == 0 && pG->A[y][e] == 0) { 401 pG->A[x][e] = 1; 402 pG->A[y][e] = 1; 403 }

404 }

405 }

406

407

408 ### Viết hàm List neighbors(Graph* pG, int u) trả về danh sách các đỉnh kề của u theo

mẫu (prototype): Vô Hướng Không chứa khuyên

409

410 List neighbors(Graph* pG, int x) {

412 make_null(&L);

413 int e, y;

414 for (y = 1; y <= pG->n; y++) {

415 if (x == y) continue;

Trang 8

416 for (e = 1; e <= G->m; e++)

417 if (pG->A[x][e] > 0 && pG->A[y][e] > 0) {

422 return L;

423 }

424

-425 "Ma trận đỉnh - đỉnh" dùng để biểu diễn các đơn đồ

thị vô hướng

426

427 Viết hàm int deg(Graph* G, int x) để tính bậc của đỉnh u theo mẫu (prototype): ( *G chứ

không phải *pG)

428

429 int deg(Graph* pG, int x){

430 int de=0;

432 for(i=1;i<=pG->n;i++)

433 if(pG->A[x][i]==1)

435 return de;

436 }

437

438

440 Viết chương trình tính và in ra màn hình đỉnh có bậc lớn nhất và bậc tương ứng của

441 Nếu có nhiều đỉnh có bật bằng nhau thì in ra đỉnh có số thứ tự nhỏ nhất

442

-443 ** #include <stdio.h>

444 #define MAX_N 100

445

446 * typedef struct {

447 int A[MAX_N][MAX_N];

449 } Graph;

450

451 * void init_graph(Graph *pG, int n) {

452 pG->n = n;

453 for (int i = 0; i < n; ++i) {

454 for (int j = 0; j < n; ++j) {

455 pG->A[i][j] = 0;

458 }

459

460 * void add_edge(Graph *pG, int u, int v) {

461 pG->A[u][v] = 1;

462 pG->A[v][u] = 1;

463 }

464

465 * int deg(Graph *pG, int u) {

466 int degree = 0;

467 for (int i = 0; i < pG->n; ++i) {

468 degree += pG->A[u][i];

470 return degree;

471 }

472

473 * int main() {

474 Graph pG;

475 int n, m;

476 scanf("%d %d", &n, &m);

477 init_graph(&pG, n);

478 * for (int i = 0; i < m; ++i) {

480 scanf("%d %d", &u, &v);

481 add_edge(&pG, u - 1, v - 1);

Trang 9

482 }

483 int maxDegree = -1;

484 int maxVertex = -1;

485 * for (int u = 0; u < n; ++u) {

486 int degree = deg(&pG, u);

487 if (degree > maxDegree || (degree == maxDegree && u < maxVertex)) {

492 *In printf("%d %d\n", maxVertex + 1, maxDegree);

493

494 return 0;

495 }

496

497

499 Hãy viết chương trình đọc đồ thị từ tập tin và hiển thị ma trận kề của đồ thị này

500

501 Giả sử đồ thị được cho là đồ thị vô hướng đơn

502

503 Đầu vào (Input):

504

505 Dữ liệu đầu vào được nhập từ tập tin dt1.txt với định dạng:

506

507 - Dòng đầu tiên chứa 2 số nguyên n và m, tương ứng là số đỉnh và số cung

508

509 - m dòng tiếp theo mỗi dòng chứa 2 số nguyên u v mô tả cung (u, v)

510

511 Đầu ra (Output):

512

513 In ra Ma trận kề (0/1) của đồ thị

514

515 #include <stdio.h>

516 #define MAX_N 100

517

518 * typedef struct {

519 int A[MAX_N][MAX_N];

521 } Graph;

522

523 * void init_graph(Graph *pG, int n) {

524 pG->n = n;

525 for (int i = 0; i < n; ++i) {

526 for (int j = 0; j < n; ++j) {

527 pG->A[i][j] = 0;

530 }

531

532 * void add_edge(Graph *pG, int u, int v) {

533 pG->A[u][v] = 1;

534 pG->A[v][u] = 1;

535 }

536

537 * void hienthi_matran(Graph *pG) {

538 for (int i = 0; i < pG->n; ++i) {

539 for (int j = 0; j < pG->n; ++j) {

540 printf("%d ", pG->A[i][j]);

542 printf("\n");

544 }

545

546 * int main() {

547 Graph pG;

548 int n, m;

549 * // Đọc file

550 FILE *file = fopen("dt1.txt", "r");

Trang 10

551 if (file == NULL) {

552 printf("Cannot open file dt1.txt\n");

555 fscanf(file, "%d %d", &n, &m);

556 init_graph(&pG, n);

557 for (int i = 0; i < m; ++i) {

559 fscanf(file, "%d %d", &u, &v);

560 add_edge(&pG, u - 1, v - 1);

562 * // Đóng file

563 fclose(file);

564 * // hien thi ma tran

565 hienthi_matran(&pG);

566 return 0;

567 }

568

569

-

-570

571

572

Ngày đăng: 01/03/2024, 22:59

TỪ KHÓA LIÊN QUAN

w