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;
}
