基础实验6-2.6 最短工期 (25分)(C语言实现)(数据结构)

基础实验6-2.6 最短工期 (25分)
一个项目由若干个任务组成,任务之间有先后依赖顺序。项目经理需要设置一系列里程碑,在每个里程碑节点处检查任务的完成情况,并启动后续的任务。现给定一个项目中各个任务之间的关系,请你计算出这个项目的最早完工时间。

输入格式:
首先第一行给出两个正整数:项目里程碑的数量 N(≤100)和任务总数 M。这里的里程碑从 0 到 N−1 编号。随后 M 行,每行给出一项任务的描述,格式为“任务起始里程碑 任务结束里程碑 工作时长”,三个数字均为非负整数,以空格分隔。

输出格式:
如果整个项目的安排是合理可行的,在一行中输出最早完工时间;否则输出"Impossible"。

输入样例 1:

9 12
0 1 6
0 2 4
0 3 5
1 4 1
2 4 1
3 5 2
5 4 0
4 6 9
4 7 7
5 7 4
6 8 2
7 8 4

输出样例 1:

18

输入样例 2:

4 5
0 1 1
0 2 2
2 1 3
1 3 4
3 2 5

输出样例 2:

Impossible

这道题目我们需要用邻接表来建立
我们首先给出邻接表的定义

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 105
#define INFINITY -10005
typedef struct AdjNode *AdjList;
struct AdjNode
{
	int index;
	int weight;
	AdjList	next;
};
typedef struct HNode
{
	AdjList FirstEdge;
}List[MAX];

typedef struct GNode *LGraph;
struct GNode
{
	int Nv;
	List head;
};

typedef struct ENode *Edge;
struct ENode
{
	int v1,v2;
	int weight;
};

然后是关于图和表的一些操作

void InsertEdge(LGraph G,Edge e)
{
	AdjList NewNode;
	NewNode=(AdjList)malloc(sizeof(struct AdjNode));
	NewNode->index=e->v2;
	NewNode->weight=e->weight;
	NewNode->next=G->head[e->v1].FirstEdge;
	G->head[e->v1].FirstEdge=NewNode;
}
LGraph CreateLGraph(int n,int m)
{
	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->head[v].FirstEdge=NULL;
	}
	for(v=0;v<m;v++)
	{
		scanf("%d%d%d",&E->v1,&E->v2,&E->weight);
		InsertEdge(G,E);
	}
	return G;
}

最后就是这道题目的关键算法
拓扑排序

int TopSort(LGraph G)
{
	int InDegree[MAX],Time[MAX],cnt=0,t=INFINITY;
	int Queue[MAX],front,rear;//队列
	int v;
	AdjList w;
	front=rear=0;
	for(v=0;v<G->Nv;v++)
	{
		Time[v]=0;
		InDegree[v]=0;
	}
	for(v=0;v<G->Nv;v++)//给各个点分配相应的度
	{
		for(w=G->head[v].FirstEdge;w;w=w->next)
		{
			++InDegree[w->index];
		}
	}
	for(v=0;v<G->Nv;v++)//度为0的节点入队
	{
		if(!InDegree[v])Queue[++rear]=v;
	}
	while(front!=rear)
	{
		v=Queue[++front];//出队
		cnt++;//计数
		for(w=G->head[v].FirstEdge;w;w=w->next)
		{
			if(Time[v]+w->weight>Time[w->index])//相应的下标存的是前几个点权重的相加之和
				Time[w->index]=Time[v]+w->weight;
			if(--InDegree[w->index]==0)//度为0的节点再次入队
				Queue[++rear]=w->index;
		}
	}
	if(cnt==G->Nv)
		{
			for(v=0;v<cnt;v++)
			if(t<Time[v])t=Time[v];//t等于最大的那个值
	printf("%d\n",t);
	}
	else//cnt没计满,表示图中一定有回路
		 printf("Impossible\n");

}

主函数入口

int main() {
    int n, m;
    LGraph G;
    scanf("%d%d", &n, &m);
    G = CreateLGraph(n, m);
    TopSort(G);
    return 0;
}

话不多说总代码如下

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 105
#define INFINITY -10005
typedef struct AdjNode *AdjList;
struct AdjNode
{
	int index;
	int weight;
	AdjList	next;
};
typedef struct HNode
{
	AdjList FirstEdge;
}List[MAX];

typedef struct GNode *LGraph;
struct GNode
{
	int Nv;
	List head;
};

typedef struct ENode *Edge;
struct ENode
{
	int v1,v2;
	int weight;
};

void InsertEdge(LGraph G,Edge e)
{
	AdjList NewNode;
	NewNode=(AdjList)malloc(sizeof(struct AdjNode));
	NewNode->index=e->v2;
	NewNode->weight=e->weight;
	NewNode->next=G->head[e->v1].FirstEdge;
	G->head[e->v1].FirstEdge=NewNode;
}
LGraph CreateLGraph(int n,int m)
{
	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->head[v].FirstEdge=NULL;
	}
	for(v=0;v<m;v++)
	{
		scanf("%d%d%d",&E->v1,&E->v2,&E->weight);
		InsertEdge(G,E);
	}
	return G;
}
int TopSort(LGraph G)
{
	int InDegree[MAX],Time[MAX],cnt=0,t=INFINITY;
	int Queue[MAX],front,rear;
	int v;
	AdjList w;
	front=rear=0;
	for(v=0;v<G->Nv;v++)
	{
		Time[v]=0;
		InDegree[v]=0;
	}
	for(v=0;v<G->Nv;v++)//给各个几点分配 度
	{
		for(w=G->head[v].FirstEdge;w;w=w->next)
		{
			++InDegree[w->index];
		}
	}
	for(v=0;v<G->Nv;v++)//度为0的节点入队
	{
		if(!InDegree[v])Queue[++rear]=v;
	}
	while(front!=rear)
	{
		v=Queue[++front];//出队
		cnt++;//计数
		for(w=G->head[v].FirstEdge;w;w=w->next)
		{
			if(Time[v]+w->weight>Time[w->index])
				Time[w->index]=Time[v]+w->weight;
			if(--InDegree[w->index]==0)
				Queue[++rear]=w->index;
		}
	}
	if(cnt==G->Nv)
		{
			for(v=0;v<cnt;v++)
			if(t<Time[v])t=Time[v];
	printf("%d\n",t);
	}
	else
		 printf("Impossible\n");

}
int main()
{
	int n,m;
	LGraph G;
	scanf("%d%d",&n,&m);
	G=CreateLGraph(n,m);
	TopSort(G);
	return 0;
}
  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值