KIỂM TRA LIÊN THÔNG MẠNH
// CT175 - Lý thuy?t d? th? (B? môn KHMT - Khoa CNTT & TT, DHCT)
// B1809362 - Truong Qu?c K? // Gi?i thu?t d?a trên ma tr?n liên thu?c (Ð?nh - cung) cho d? th? có hu?ng và vô hu?ng #include <stdio.h> #define MAX_VERTICES 100 #define MAX_EDGES 500 #define MAX_ELEMENTS 100 #define white 0 #define black 1 #define gray 2 int mark[MAX_VERTICES]; int parent[MAX_VERTICES]; int color[MAX_VERTICES]; int cycle; // C?u trúc List typedef int ElementType; typedef struct { ElementType data[MAX_ELEMENTS]; int size; } List; // C?u trúc Stack typedef struct { int data[MAX_ELEMENTS]; int size; }Stack; // C?u trúc Queue typedef struct { int data[MAX_ELEMENTS]; int front, rear; }Queue; // C?u trúc Graph typedef struct { int n, m; int A[MAX_VERTICES][MAX_EDGES]; }Graph; // Cài d?t Queue void make_null_queue(Queue *Q) { Q->front = 0; Q->rear = -1; } void push_queue(Queue *Q, int x) { Q->rear++; Q->data[Q->rear] = x; } int top_queue(Queue *Q) { return Q->data[Q->front]; } void pop_queue(Queue *Q) { Q->front++; } int empty_queue(Queue *Q) { return Q->front>Q->rear; } // Cài d?t danh sách void make_null_list(List* L) { L->size = 0; } void push_list(List* L, ElementType x) { L->data[L->size] = x; L->size++; } ElementType element_at_list(List* L, int i) { return L->data[i-1]; } int count_list(List* L) { return L->size; } int empty_list(List *L) { return L->size == 0; } // Cài d?t Stack void make_null_stack(Stack *S) { S->size = 0; } void push_stack(Stack *S, int x) { S->data[S->size] = x; S->size++; } int top_stack(Stack *S) { return S->data[S->size - 1]; } int pop_stack(Stack *S) { return S->size--; } int empty_stack(Stack *S) { return S->size == 0; } // Bi?n h? tr? liên thông m?nh (d? th? có hu?ng) int num[MAX_VERTICES]; int min_num[MAX_VERTICES]; Stack S; int on_stack[MAX_VERTICES]; int k = 0; // T?o d? th? r?ng void init_graph(Graph *G, int n, int m) { int i, j; G->n = n; G->m = m; for(i = 1; i <= n; i++) { for(j = 1; j <= m; j++) { G->A[i][j] = 0; } } } // Thêm cung vô hu?ng void add_edge(Graph *G, int e, int x, int y) { G->A[x][e] = 1; G->A[y][e] = 1; } // Thêm cung có hu?ng void add_vecto(Graph *G, int e, int x, int y) { G->A[x][e] = 1; G->A[y][e] = -1; } // Nh?p danh sách cung vô hu?ng t? bàn phím void scan_graph(Graph *G) { int n, m, u, v, e; scanf("%d%d", &n, &m); init_graph(G, n, m); for (e = 1; e <= m; e++) { scanf("%d%d", &u, &v); add_edge(G, e, u, v); } } // Nh?p danh sách cung có hu?ng t? bàn phím void scan_vecto_graph(Graph *G) { int n, m, u, v, e; scanf("%d%d", &n, &m); init_graph(G, n, m); for (e = 1; e <= m; e++) { scanf("%d%d", &u, &v); add_vecto(G, e, u, v); } } // Nh?p tu?n t? ma tr?n void scan_obo_graph(Graph *G) { int n, m; scanf("%d%d", &n, &m); init_graph(G, n, m); int i, j; G->n = n; G->m = m; for(i = 1; i <= n; i++) { for(j = 1; j <= m; j++) { scanf("%d", &G->A[i][j]); } } } // In ma tr?n d? th? void print_graph(Graph *G) { int i, j; printf("\nMatrix %dx%d: \n", G->n, G->m); for(i = 1; i <= G->n; i++) { for(j = 1; j <= G->m; j++) { printf("%d ", G->A[i][j]); } printf("\n"); } } // Ð?c d? th? t? file (vô hu?ng) dùng add_vecto() n?u có hu?ng void read_graph(FILE *F, Graph *G) { int e, u ,v, m, n; fscanf(F, "%d%d", &n, &m); init_graph(G, n, m); for(e = 1; e <= m; e++) { fscanf(F, "%d%d", &u, &v); add_edge(G, e, u, v); } } // Ki?m tra k? int check_adj(Graph *G, int x, int y) { int j, temp; for(j = 1; j <= G->m; j++) { if((G->A[x][j] > 0) && (G->A[y][j] > 0)) { if(x == y) temp = 0; else { temp = 1; break; } } else temp = 0; } return temp; } // Ki?m tra k? có hu?ng int check_adj_io(Graph *G, int x, int y) { int j, temp; for(j = 1; j <= G->m; j++) { if(((G->A[x][j] > 0) && (G->A[y][j] > 0)) || ((G->A[x][j] == 1) && (G->A[y][j] == -1))) { if(x == y) temp = 0; else { temp = 1; break; } } else if((G->A[x][j] == -1) && (G->A[y][j] == -1)) temp = 1; else temp = 0; } return temp; } // B?c ra d?nh x int degree_out(Graph *G, int x) { int e, deg = 0; for(e = 1; e <= G->m; e++) { if(G->A[x][e] == 1) deg++; } return deg; } // B?c vào d?nh x int degree_in(Graph *G, int x) { int e, deg = 0; for(e = 1; e <= G->m; e++) { if(G->A[x][e] == -1) deg++; } return deg; } // Tr? v? danh sách k? d?nh x vô hu?ng List neighbors(Graph *G, int x) { int y; List list; make_null_list(&list); for(y = 1; y <= G->n; y++) if(check_adj(G, x, y)) { push_list(&list, y); } return list; } // Tr? v? danh sách k? d?nh x có hu?ng List neighbors_io(Graph *G, int x) { int y; List list; make_null_list(&list); for(y = 1; y <= G->n; y++) if(check_adj_io(G, x, y)) { push_list(&list, y); } return list; } // T?o l?i các d?nh chua du?c dánh d?u void reset_mark(Graph *G) { int i; for(i = 1; i <= G->n; i++) mark[i] = 0; } // Xoá các d?nh cha void reset_parent(Graph *G) { int i; for(i = 1; i <= G->n; i++) parent[i] = -1; } // Duy?t theo chi?u sâu, vô hu?ng void DFS(Graph *G, int x) { Stack S; make_null_stack(&S); push_stack(&S, x); parent[x] = 0; int i; while(!empty_stack(&S)) { int u = top_stack(&S); pop_stack(&S); if(mark[u] == 1) continue; printf("Duyet: %d\n", u); mark[u] = 1; List L = neighbors(G, u); for(i = 1; i <= L.size; i++) { int v = element_at_list(&L, i); if(mark[v] == 0) { push_stack(&S, v); parent[v] = u; } } } } // Duy?t theo chi?u r?ng, vô hu?ng void BFS(Graph *G, int x) { Queue Q; make_null_queue(&Q); push_queue(&Q, x); parent[x] = 0; int i; while(!empty_queue(&Q)) { int u = top_queue(&Q); pop_queue(&Q); if(mark[u] == 1) continue; printf("Duyet: %d\n", u); mark[u] = 1; List L = neighbors(G, u); for(i = 1; i <= L.size; i++) { int v = element_at_list(&L, i); if(mark[v] == 0) { push_queue(&Q, v); parent[v] = u; } } } } // Duy?t theo chi?u sâu d? quy, vô hu?ng void DFS_Recursion(Graph *G, int u, int p) { int i; if(mark[u] == 1) return; printf("Duyet: %d\n", u); parent[u] = p; mark[u] = 1; List L = neighbors(G, u); for(i = 1; i <= L.size; i++) { int v = element_at_list(&L, i); DFS_Recursion(G, v, u); } } // Duy?t d? quy u void traversal(Graph *G, int u) { int i; if(mark[u] == 1) return; mark[u] = 1; List L = neighbors(G, u); for(i = 1; i <= L.size; i++) { int v = element_at_list(&L, i); traversal(G, v); } } // Ð?m s? thành ph?n liên thông c?a d? th? vô hu?ng int count_connected_components(Graph *G) { int i, cmt; for(i = 1; i <= G->n; i++) if(mark[i] == 0) { traversal(G, i); cmt++; } return cmt; } // Duy?t d? quy u (chu trình vô hu?ng) void traversal_cycle(Graph *G, int u, int p) { int i; color[u] = gray; if(mark[u] == 1) return; mark[u] = 1; List L = neighbors(G, u); for(i = 1; i <= L.size; i++) { int v = element_at_list(&L, i); if(v == p) continue; if(color[v] == gray) { cycle = 1; return; } if(color[v] == white) traversal_cycle(G, v, u); } color[u] = black; } // Ki?m tra chu trình d? th? vô hu?ng int contains_cycle(Graph *G) { int i; for(i = 1; i <= G->n; i++) color[i] = white; cycle = 0; for(i = 1; i <= G->n; i++) if(color[i] == white) traversal_cycle(G, i, 0); return cycle; } // Duy?t d? quy u (chu trình có hu?ng) void traversal_cycle_io(Graph *G, int u) { int i; color[u] = gray; if(mark[u] == 1) return; mark[u] = 1; List L = neighbors_io(G, u); for(i = 1; i <= L.size; i++) { int v = element_at_list(&L, i); if(color[v] == gray) { cycle = 1; return; } if(color[v] == white) traversal_cycle_io(G, v); } color[u] = black; } // Ki?m tra chu trình d? th? có hu?ng int contains_cycle_io(Graph *G) { int i; for(i = 1; i <= G->n; i++) color[i] = white; cycle = 0; for(i = 1; i <= G->n; i++) if(color[i] == white) traversal_cycle_io(G, i); return cycle; } // Tìm giá tr? nh? nh?t int min(int a, int b) { int result; if(a < b) result = a; else result = b; return result; } int str = 0; // Tìm s? thành ph?n liên thông m?nh void strong_connect(Graph *G, int u) { k++; num[u] = min_num[u] = k; push_stack(&S, u); on_stack[u] = 1; List L = neighbors_io(G, u); int i; for(i = 1; i <= L.size; i++) { int v = element_at_list(&L, i); if(num[v] < 0) { strong_connect(G, v); min_num[u] = min(min_num[u], min_num[v]); } else if (on_stack[v]) min_num[u] = min(min_num[u], num[v]); } //printf("min_num[%d] = %d\n", u, min_num[u]); if(num[u] == min_num[u]) { //printf("%d la dinh khop\n", u); int w; do { w = top_stack(&S); pop_stack(&S); on_stack[w] = 0; } while (w != u); str++; } } void check_strong_connect(Graph *G) { int v; make_null_stack(&S); k = 1; for(v = 1; v <= G->n; v++) { num[v] = -1; on_stack[v] = 0; } for(v = 1; v <= G->n; v++) if(num[v] == -1) strong_connect(G, v); //printf("%d\n", str); } int main() { // T?o m?t d? th? Graph dothi; // Bi?n l?p // int i, u; // Các thao tác scan_vecto_graph(&dothi); // Ðánh d?u các d?nh chua duy?t reset_mark(&dothi); reset_parent(&dothi); // Duy?t d? th? //for(i = 1; i <= dothi.n; i++) // if(mark[i] == 0) // DFS(&dothi, i); check_strong_connect(&dothi); printf("%d", str); return 0; }