# PTA 图 关键路径 测试点2和5

0

``````#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define IMPOSSIBLE 1000000

typedef struct E * Edge;   //边
struct E{
int e1, e2;
int take;
};

typedef struct G * Graph;
struct G{
int N;  //节点个数
int E;  //边个数
int ** Matrix;
};

typedef struct Q *Queue;    //队列
struct Q{
int a[105];
int front, rear;
};

Graph CreateGraph(int, int);
void InsertGraph(Graph, Edge);
int * GetEarilestCost(Graph, int *);    //得到每个节点了最早完成时间
int * GetLatestCost(Graph, int *, int *);
void PrintCriticalPath(Graph, int *, int *);

Queue CreateQueue();        //建队列
void InQueue(Queue , int);  //入队
int OutQueue(Queue);        //出队
bool IsEmpty(Queue);

int main()
{
int N, M, i, ecost = 0;
int *Earliest, *Latest;

scanf("%d %d", &N, &M);
Graph G = CreateGraph(N, M);

int *Indegree = (int *)malloc( sizeof(int) * (N+1) );
int *Outdegree = (int *)malloc( sizeof(int) * (N+1) );
for( i=0; i<=N; ++i ){
Indegree[i] = 0;
Outdegree[i] = 0;
}

Edge E = (Edge)malloc(sizeof(struct E));
for( i=1; i<=G->E; ++i ){
scanf("%d %d %d", &E->e1, &E->e2, &E->take);
InsertGraph(G, E);
Indegree[E->e2]++;
Outdegree[E->e1]++;
}
free(E);

Earliest = GetEarilestCost(G, Indegree);
if( !Earliest )  printf("0\n");    //有回路
else{
for( i=1; i<=G->N; ++i ){
if( Earliest[i] > ecost )
ecost = Earliest[i];
}
printf("%d\n", ecost);
Latest = GetLatestCost(G, Outdegree, Earliest);
/*for( i=1; i<=G->N; ++i ){
printf("%d   %d\n", Earliest[i], Latest[i]);
}*/

PrintCriticalPath(G, Earliest, Latest);
}

return 0;
}

Graph CreateGraph(int N, int M)
{
int i, j;

Graph G = (Graph)malloc(sizeof(struct G));
G->Matrix = (int **)malloc( sizeof(int *) * (N+1) );
if( !G || !G->Matrix )   printf("Out of memory!");
for( i=1; i<=N; ++i ){
G->Matrix[i] = (int *)malloc( sizeof(int) * (N+1) );
if( !G->Matrix[i] ) printf("Out of memory!");
for( j=1; j<=N; ++j ){
G->Matrix[i][j] = IMPOSSIBLE;
}
}
G->N = N;
G->E = M;

return G;
}
void InsertGraph(Graph G, Edge E)
{
G->Matrix[E->e1][E->e2] = E->take;
}
int * GetEarilestCost(Graph G, int *Indegree)
{
int i, n, count = 0;  //n是弹出队列的节点 ，count用于计算节点个数，若循环结束时count不等于总节点个数，说明有回路
Queue Q = CreateQueue();

int *Cost = (int *)malloc( sizeof(int) * (G->N+1) );
for( i=1; i<=G->N; ++i ){
Cost[i] = 0;    //每个cost都初始化为0
if( !Indegree[i] )  //找出初始入度为零节点，进入队列
InQueue(Q, i);
}

while( !IsEmpty(Q) ){   //只要队列不空
n = OutQueue(Q);
count++;    //计数器
for( i=1; i<=G->N; ++i ){
if( G->Matrix[n][i] == IMPOSSIBLE )
continue;
if( !--Indegree[i] ){  //队列每弹出一个节点，他指向节点的入度减1，当入度为0时，入队列
InQueue(Q, i);
}
if( Cost[i] < G->Matrix[n][i] + Cost[n])   //最早完成时间是所有到这个节点完成时间中最长的那个，
Cost[i] = G->Matrix[n][i] + Cost[n];
}
}
free(Q);
if( count != G->N ) //说明有回路
return NULL;
else return Cost;
}
int * GetLatestCost(Graph G, int * Outdegree, int * Earliest)
{
int i, n;
Queue Q = CreateQueue();

int *Cost = (int *)malloc( sizeof(int) * (G->N+1) );
for( i=1; i<=G->N; ++i ){
Cost[i] = IMPOSSIBLE;
if( !Outdegree[i] ){  //找出初始入度为零节点，进入队列
InQueue(Q, i);
Cost[i] = Earliest[i];
}
}

while( !IsEmpty(Q) ){   //只要队列不空
n = OutQueue(Q);
for( i=1; i<=G->N; ++i ){
if( G->Matrix[i][n] == IMPOSSIBLE )
continue;
if( !--Outdegree[i] ){  //队列每弹出一个节点，他指向节点的入度减1，当入度为0时，入队列
InQueue(Q, i);
}
if( Cost[i] > Cost[n] - G->Matrix[i][n] )   //最早完成时间是所有到这个节点完成时间中最长的那个，
Cost[i] = Cost[n] - G->Matrix[i][n];
}
}
free(Q);

return Cost;
}
void PrintCriticalPath(Graph G, int *Earilest, int *Latest)
{
int i, j;

for( i=1; i<=G->N; ++i ){
for( j=G->N; j>=1; --j ){
if( G->Matrix[i][j] == IMPOSSIBLE )
continue;
if( G->Matrix[i][j] + Earilest[i] == Latest[j] )
printf("%d->%d\n", i, j);
}
}
}

Queue CreateQueue()
{
Queue Q = (Queue)malloc(sizeof(struct Q));
Q->front = Q->rear = 0;
return Q;
}
void InQueue(Queue Q, int i)
{
Q->a[Q->rear] = i;
Q->rear++;
}
int OutQueue(Queue Q)
{
if( !IsEmpty(Q) ){
int i = Q->a[Q->front];
Q->front++;
return i;
}
else printf("wrong\n");
}
bool IsEmpty(Queue Q)
{
if( Q->front == Q->rear )
return true;
else
return false;
}
``````

り罐罐。 | 初学一级 | 园豆：46

@。淑女范erり: 已修改

り罐罐。 1年前

您需要登录以后才能回答，未注册用户请先注册