BÀI TOÁN THI CÔNG
//Thi Cong // Adjacency Matrix (Vertices-Vertices) [Directed]
#include <stdio.h> #define MAX_ELEMENTS 100 //List Structure typedef int ElementType; typedef struct { ElementType data[MAX_ELEMENTS]; int size; }List; //Stack Structure typedef struct { int data[MAX_ELEMENTS]; int size; }Stack; //Queue Structure typedef struct { int data[MAX_ELEMENTS]; int front, rear; }Queue; /* Init List */ //Make null a list void make_null_list(List* L) { L->size = 0; } //Pust List void push_list(List* L, ElementType x) { L->data[L->size] = x; L->size++; } //Return an element at list ElementType element_at_list(List* L, int i) { return L->data[i-1]; } //Count amount element in list int count_list(List* L) { return L->size; } //Empty a list int empty_list(List *L) { return L->size == 0; } //Copy list void copy_list(List* L1, List* L2) { int i; make_null_list(L1); for(i = 1; i <= L2->size; i++) { push_list(L1, element_at_list(L2, i)); } } /* Init Queue */ //Make null a queue void make_null_queue(Queue *Q) { Q->front = 0; Q->rear = -1; } //Push Queue void push_queue(Queue *Q, int x) { Q->rear++; Q->data[Q->rear] = x; } //Top Queue int top_queue(Queue *Q) { return Q->data[Q->front]; } //Pop Queue void pop_queue(Queue *Q) { Q->front++; } //Empty a Queue int empty_queue(Queue *Q) { return Q->front>Q->rear; } /* Init Stack */ //Make null a stack void make_null_stack(Stack *S) { S->size = 0; } //Push Stack void push_stack(Stack *S, int x) { S->data[S->size] = x; S->size++; } //Top stack int top_stack(Stack *S) { return S->data[S->size - 1]; } //Pop stack int pop_stack(Stack *S) { return S->size--; } //Empty a stack int empty_stack(Stack *S) { return S->size == 0; } #define MAX 200 #define INFINITY 999999 int d[MAX]; int t[MAX]; int T[MAX]; //Graph Structure typedef struct { int n; int A[MAX][MAX]; }Graph; /* Init A Basic Graph */ //Init an empty graph void init_graph(Graph* G, int n) { int i, j; G->n = n; for(i = 1; i <= n; i++) for(j = 1; j <= n; j++) G->A[i][j] = 0; } // Add an edge void add_vecto(Graph *G, int x, int y) { G->A[x][y] = 1; G->A[y][x] = -1; } //Scan any edge void scan_vecto_graph(Graph *G) { int n,u,v,x; // freopen("DuAnXayNha.txt","r",stdin); scanf("%d", &n); init_graph(G,n+2); d[n+1]=0; for (u=1;u<=n;u++){ scanf("%d",&d[u]); do{ scanf("%d",&x); if (x>0) add_vecto(G,x,u); }while(x>0); } //them cung noi alpha for(u=1;u<=n;u++){ int deg_neg =0; for(x=1;x<=n;x++) if(G->A[x][u]>0) deg_neg++; if(deg_neg ==0 ) add_vecto(G,n+1,u); } //them cung noi beta for(u=1;u<=n;u++){ int deg_pos = 0; for(v=1;v<=n;v++) if(G->A[u][v]>01) deg_pos++; if(deg_pos ==0 ) add_vecto(G,u,n+2); } } //Scan a matrix void scan_obo_graph(Graph *G) { int n; scanf("%d", &n); init_graph(G, n); int i, j; G->n = n; for(i = 1; i <= n; i++) { for(j = 1; j <= n; j++) { scanf("%d", &G->A[i][j]); } } } //Print a matrix void print_graph(Graph *G) { int i, j; printf("\nMatrix %dx%d: \n", G->n, G->n); for(i = 1; i <= G->n; i++) { for(j = 1; j <= G->n; j++) { printf("%d ", G->A[i][j]); } printf("\n"); } } //Return IN degree of a vertice int degree_in(Graph* G, int x) { int y, deg = 0; for(y = 1; y <= G->n; y++) if(G->A[x][y] < 0) deg++; return deg; } //Has edge int has_edge(Graph* G, int x, int y) { return ((G->A[x][y] != 0) && (G->A[y][x] != 0)) ? 1 : 0; } //Check Adjacency int check_direction(Graph* G, int x, int y) { return ((G->A[x][y] == 1) && (G->A[y][x] == -1)) ? 1 : 0; } //Return Out Vertical Neighbor List ++ List neighbors_out(Graph *G, int x) { int y; List list; make_null_list(&list); for(y = 1; y <= G->n; y++) if(check_direction(G, x, y) && has_edge(G, x, y)) { push_list(&list, y); } return list; } void TopoSort(Graph* G, List* L) { int u, d[MAX]; Queue Q; make_null_queue(&Q); for(u = 1; u <= G->n; u++) d[u] = 0; for(u = 1; u <= G->n; u++) d[u] = degree_in(G, u); for(u = 1; u <= G->n; u++) if(d[u] == 0) push_queue(&Q, u); make_null_list(L); while(!empty_queue(&Q)) { int u = top_queue(&Q); pop_queue(&Q); push_list(L, u); int v; for(v = 1; v <= G->n; v++) { if(has_edge(G, u, v)) { d[v]--; if(d[v] == 0) push_queue(&Q, v); } } } } int min(int a, int b) { return a < b ? a : b; } int max(int a, int b) { return a < b ? b : a; } void ThiCong(Graph* G, List* L) { int n = G->n-2; t[n+1]=0; int i ,v; for(i=2;i<=L->size;i++){ int u=element_at_list(L,i); t[u]=-1; for (v = 1; v <= G->n; v++) if(check_direction(G, v, u)) t[u]=max(t[u],t[v]+d[v]); } // tinh T[u] T[n+2]=t[n+2]; for(i=L->size-1;i>=1;i--){ int u=element_at_list(L,i); T[u]=INFINITY; for (v = 1; v <= G->n; v++) if(check_direction(G, u, v)) T[u]=min(T[u],T[v]-d[u]); } } int main() { Graph dothi; // freopen("dt.txt","r",stdin); scan_vecto_graph(&dothi); List L; TopoSort(&dothi, &L); ThiCong(&dothi, &L); int i; printf("%d\n", T[dothi.n]); for(i = 1; i <= dothi.n; i++) printf("%d-%d\n", t[i], T[i]); return 0; }