BÀI TOÁN PHẦN MỀM THI CÔNG Adjacency Matrix
//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* work_at, int* start)
{
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);
}
//scanf("%d%d", work_at, start);
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);
}
for(u = 1; u <= n; u++)
{
int deg_pos = 0;
for(v = 1; v <= n; v++)
if(G->A[u][v] > 0)
deg_pos++;
if(deg_pos == 0)
add_vecto(G, u, n+2);
}
}
//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]);
}
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()
{
int work_at, start;
Graph dothi;
scan_vecto_graph(&dothi, &work_at, &start);
List L;
TopoSort(&dothi, &L);
ThiCong(&dothi, &L);
int j;
for(j=1;j<=dothi.n;j++)
if(T[j]==t[j])
printf("%d\n",j);
return 0;
}
