#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 105
#define INFINITY -10005
#define MAX_VERTEX_NUM 100
#define ERROR 0
#define OK 1
int TopOrder[MAX_VERTEX_NUM];
int time[MAX_VERTEX_NUM];
typedef int Status;
struct AdjVNode//邻接点
{
int adjvex;
int weight;
AdjVNode *next;
};
typedef struct VNode//顶点
{
AdjVNode *FirstEdge;
} AdjList[MAX_VERTEX_NUM];
//typedef struct GNode *LGraph;
typedef struct GNode//图
{
int Nv;//顶点数
int Ne;//边数
AdjList vertices;//邻接表
}*LGraph;
//typedef struct ENode *Edge;
typedef struct ENode//边
{
int v1,v2;
int weight;
}*Edge;
typedef struct QNode//链队列
{
int data;
struct QNode *next;
} QNode,*QueuePtr;
typedef struct
{
QueuePtr front; //对头指针
QueuePtr rear; //队尾指针
} LinkQueue;
Status InitQueue(LinkQueue &Q)
{
//构造一个空队列Q
Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
if (!Q.front)
exit(0);
Q.front->next = NULL;
return OK;
}
Status QueueEmpty(LinkQueue Q)
{
//判断队列是否为空
if (Q.front == Q.rear)
return 1;
return 0;
}
Status EnQueue(LinkQueue &Q, int e)
{
//插入元素e为Q的新的队尾元素
QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
if (!p)
return ERROR;
p->next = NULL;
p->data = e;
Q.rear->next = p;
Q.rear = p;
return OK;
}
Status DeQueue(LinkQueue &Q, int &e)
{
//若队列不空,则删除Q的队头元素,用e返回其值,并返回OK
if (Q.front == Q.rear)
return ERROR;
QueuePtr p;
p = Q.front->next;
e = p->data;
Q.front->next = p->next;
if (Q.rear == p)
Q.rear = Q.front;
free(p);
return OK;
}
LGraph CreateLGraph(int n,int m)
{
AdjVNode *NewNode;
int v;
LGraph G=(LGraph)malloc(sizeof(struct GNode));
Edge E=(Edge)malloc(sizeof(struct ENode));
G->Nv=n;
for(v=0; v<n; v++)
{
G->vertices[v].FirstEdge=NULL;
}
for(v=0; v<m; v++)
{
scanf("%d%d%d",&E->v1,&E->v2,&E->weight);
//InsertEdge(G,E);
NewNode=(AdjVNode*)malloc(sizeof(AdjVNode));
NewNode->adjvex=E->v2;
NewNode->weight=E->weight;
NewNode->next=G->vertices[E->v1].FirstEdge;
G->vertices[E->v1].FirstEdge=NewNode;
}
return G;
}
int TopSort(LGraph Graph)//拓扑排序
{
int Indegree[MAX_VERTEX_NUM], cnt;
int V;
AdjVNode *W;
LinkQueue Q;
InitQueue(Q);
for( V = 0; V<Graph->Nv; V++)
Indegree[V]=0;
for( V = 0; V<Graph->Nv; V++)
for(W = Graph->vertices[V].FirstEdge; W; W = W->next)
Indegree[W->adjvex]++; //入度增加
for(V = 0; V < Graph->Nv; V++)
if(Indegree[V]==0)
EnQueue(Q, V);
cnt = 0;
while(!QueueEmpty(Q))
{
DeQueue(Q,V);
//最短工期
for(W=Graph->vertices[V].FirstEdge; W!=NULL; W = W->next)
{
if(time[W->adjvex]<time[V]+W->weight)
time[W->adjvex]=time[V]+W->weight;
}
TopOrder[cnt++] = V;
for(W=Graph->vertices[V].FirstEdge; W!=NULL; W = W->next)
{
if(--Indegree[W->adjvex]==0)
EnQueue(Q, W->adjvex);
}
}
if(cnt != Graph->Nv)
return -1;
else
return 1;
}
int main()
{
int n,m;
LGraph G;
scanf("%d%d",&n,&m);
G=CreateLGraph(n,m);
int flag=TopSort(G);
if(flag==1)
{
int Max=time[0];
for(int i=1; i<G->Nv; i++)
{
if(time[i]>Max)
Max=time[i];
}
printf("%d",Max);
}
else
printf("Impossible");
return 0;
}
最短工期
最新推荐文章于 2024-11-28 10:01:51 发布
本文介绍了一种基于拓扑排序求解最短工期问题的算法。首先定义了图的数据结构,包括邻接表、链队列等,并实现了图的创建、初始化队列、入队、出队等操作。接着,通过拓扑排序计算每个任务的最早开始时间,最终找到最短工期。代码中展示了如何读取边和顶点信息,以及如何进行拓扑排序和计算最短工期。
3620

被折叠的 条评论
为什么被折叠?



