工程安排(拓扑排序)

2023-11-12

读入文件project.txt:

8
10
1 2 3 4 5 6 7 8
1,2,6,A
1,5,2,B
2,3,3,C
2,4,5,D
2,5,3,E
3,7,2,F
4,7,3,G
5,6,4,H
6,7,2,I
7,8,2,J

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 30
typedef struct node  //边表结点
{
    int adjvex;   //下标
    int weight;  //权值
    char letter;  //项目序号
    struct node *next;
}EdgeNode;
typedef struct   //顶点表结点
{
    int vertexdata; //顶点数据域
    int in;   //顶点入度
    EdgeNode * firstedge;//边链表头指针
}VertexNode;

void CreatGraph(FILE *fp,VertexNode *G,int vertexnum,int edgenum)  //生成图的邻接表
{
    int i;
    int begin,end,edgevalue;
    char pro;
    EdgeNode *p;
    for(i=0;i<vertexnum;i++)  //初始化
    {
        G[i].in = 0;
        G[i].firstedge = NULL;
    }
    printf("顶点值:\n");
    for(i=0;i<vertexnum;i++)
    {
        fscanf(fp," %d",&G[i].vertexdata);
        printf("%d  ",G[i].vertexdata);
    }
    printf("\n边的起始点、终点、项目序号和项目天数\n");
    for(i=0;i<edgenum;i++)
    {
        p=(EdgeNode*)malloc(sizeof(EdgeNode));
        fscanf(fp," %d,%d,%d,%c",&begin,&end,&edgevalue,&pro);
        printf("%d  %d  %c  %d\n",begin,end,pro,edgevalue);
        p->adjvex = end-1;
        p->weight = edgevalue;
        p->letter = pro;
        p->next = G[begin-1].firstedge;
        G[begin-1].firstedge = p;  //头插
        G[end-1].in++;
    }
}

void LeastDay(VertexNode *G,int vertexnum,int edgenum) //求关键路径
{
    int i=0,j=0,k=0,n=0,days=0,quantity;
    int key[vertexnum]; //关键路径的顶点
    int front,rear,*Queue;
    front = rear=-1;
    int ve[MAX_LEN]={0}; //顶点最早发生时间
    int vl[MAX_LEN]={0};  //顶点最晚发生时间
    int ee[MAX_LEN]={0};  //活动最早发生时间
    int el[MAX_LEN]={0};  //活动最晚发生时间
    EdgeNode *p;
    Queue = (int*)malloc(vertexnum*sizeof(int));
    for(i=0;i<vertexnum;i++)
    {
        if(G[i].in ==0)   //入度为0的顶点入队
            Queue[++rear]=i;
        quantity++;
    }
    while(front!=rear)  //先广遍历求ve
    {
        j = Queue[++front];
        quantity++;
        p = G[j].firstedge;
        while(p)
        {
            k = p->adjvex;
            G[k].in--;
            if((ve[j]+p->weight)>ve[k])
                ve[k] = ve[j]+p->weight;
            if(G[k].in ==0)
                Queue[++rear] = k;
            p=p->next;
        }
    }
    if(quantity<vertexnum)
    {
        printf("此图有回路,无法计算关键路径!\n");
        return;
    }
    days = ve[vertexnum-1];  //总天数
    for(i=0;i<vertexnum;i++)
        vl[i] = days;
    for(i=vertexnum-2;i>=0;i--)  //回退阶段求vl
    {
        j = Queue[i];
        p = G[j].firstedge;
        while(p)
        {
            k = p->adjvex;
            if((vl[k]-p->weight)<vl[j])
                vl[j] = vl[k]-p->weight;
            p=p->next;
        }
    }
    i = -1;
    for(j=0;j<vertexnum;j++)
    {
        p = G[j].firstedge;
        while(p)
        {
            k = p->adjvex;
            ee[++i]=ve[j];   //求ee ,E(i)=VE(j)
            el[i]=vl[k]-p->weight;  //求el , L(i)=VL(k)-ACT(ai)
            if(el[i]==ee[i])
            {
                printf("关键活动:\n ");
                printf("起点 %d   终点 %d  ",G[j].vertexdata ,G[k].vertexdata);
                if(G[j].firstedge->adjvex==G[k].vertexdata-1)
                    printf("项目序号%c\n",G[j].firstedge->letter);
                else
                    printf("项目序号%c\n",G[j].firstedge->next->letter);
                key[n]=G[j].vertexdata;
                n++;
            }
            p=p->next;
        }
    }
    key[n] = G[vertexnum-1].vertexdata;
    printf("关键路径为:\n");
    for(i=0;i<=n;i++)
    {
        printf("%d",key[i]);
        if(key[i]!=G[vertexnum-1].vertexdata)
            printf("--->");
    }
    printf("\n");
    printf("工程所需最短时间: %d天\n",days);
}

int main()
{
    FILE *fp;
    int vertexnum,edgenum;
    VertexNode *G;
    fp=fopen("project.txt","r");
    if(fp==NULL)
    {
        printf("读取文件project.txt失败!\n");
        exit(0);
    }
    printf("数据已从文件中读入!\n");
    fscanf(fp," %d",&vertexnum);
    fscanf(fp," %d",&edgenum);
    printf("顶点数%d  边数%d\n",vertexnum,edgenum);
    G=(VertexNode*)malloc(vertexnum*sizeof(VertexNode));
    CreatGraph(fp,G,vertexnum,edgenum);
    LeastDay(G,vertexnum,edgenum);
    return 0;
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

工程安排(拓扑排序) 的相关文章

  • 五大常用经典算法

    五大常用算法之一 分治算法 一 基本概念 在计算机科学中 分治法是一种很重要的算法 字面上的解释是 分而治之 就是把一个复杂的问题分成两个或更多的相同或相似的子问题 再把子问题分成更小的子问题 直到最后子问题可以简单的直接求解 原问题的解即
  • 以OpenGL/ES视角介绍gfx-hal(Vulkan) Shader/Program接口使用

    文档列表见 Rust 移动端跨平台复杂图形渲染项目开发系列总结 目录 背景 The right way to tackle this in Vulkan is to use resource descriptors A descriptor
  • 50个c/c++源代码网站

    C C 是最主要的编程语言 这里列出了50名优秀网站和网页清单 这些网站提供c c 源代码 这份清单提供了源代码的链接以及它们的小说明 我已尽力包括最佳的C C 源代码的网站 这不是一个完整的清单 您有建议可以联系我 我将欢迎您的建 议 以
  • 将二叉树转为有序的双向链表

    一 题目要求 输入一棵二叉排序树 现在要将该二叉排序树转换成一个有序的双向链表 而且在转换的过程中 不能创建任何新的结点 只能调整树中的结点指针的指向来实现 include
  • BP神经网络与Python实现

    人工神经网络是一种经典的机器学习模型 随着深度学习的发展神经网络模型日益完善 联想大家熟悉的回归问题 神经网络模型实际上是根据训练样本创造出一个多维输入多维输出的函数 并使用该函数进行预测 网络的训练过程即为调节该函数参数提高预测精度的过程
  • Hash table and application in java

    查找的效率取决于在查找是比较的次数 次数越少效率越高 反之越低 最理想的情况是无需比较 一次存取便能找到所查找的记录 根据对应关系f找到给定值K的像f K hash function 应运而生 由此思想建的表称为hash table 集合h
  • 用 Java 实现的八种常用排序算法

    八种排序算法可以按照如图分类 前置知识 1 算法稳定性 在一个序列中 能保证两个相等的数 经过排序之后 其在序列的前后位置顺序不变 A1 A2 排序前 A1 在 A2 前面 排序后 A1 还在 A2 前面 2 时间复杂度 时间复杂度是用于衡
  • DDP入门

    DDP 即动态动态规划 可以用于解决一类带修改的DP问题 我们从一个比较简单的东西入手 最大子段和 带修改的最大子段和其实是常规问题了 经典的解决方法是用线段树维护从左 右开始的最大子段和和区间最大子段和 然后进行合并 现在我们换一种方法来
  • SDUT--OJ《数据结构与算法》实践能力专题训练6 图论

    A 数据结构实验之图论一 基于邻接矩阵的广度优先搜索遍历 Description 给定一个无向连通图 顶点编号从0到n 1 用广度优先搜索 BFS 遍历 输出从某个顶点出发的遍历序列 同一个结点的同层邻接点 节点编号小的优先遍历 Input
  • 循环单链表(C语言版)

    前言 小可爱们 本次一起来看看循环单链表吧 嘻嘻 一 循环单链表的定义 循环单链表是单链表的另一种形式 其结构特点链表中最后一个结点的指针域不再是结束标记 而是指向整个链表的第一个结点 从而使链表形成一个环 和单链表相同 循环链表也有带头结
  • 以太坊系列之十五: 以太坊数据库

    以太坊数据库中都存了什么 以太坊使用的数据库是一个NOSQL数据库 是谷歌提供的开源数据leveldb 这里尝试通过分析以太坊数据库存储了什么来分析以太坊可能为我们提供哪些关于区块链的API 存储内容 NOSQL是一个key value数据
  • 链表面试题(一):反转链表的算法实现

    关于链表的考察 链表是面试里面经常涉及到的考点 因为链表的结构相比于Hashmap Hashtable Concurrenthashmap或者图等数据结构简单许多 对于后者更多面试的侧重点在于其底层实现 比如Hashmap中Entry
  • 区块链中的哈希算法

    区块链中的密码学 密码学在区块链中的应用主要有两个 哈希算法与非对称加密算法 这次主要对哈希算法进行详细的说明 哈希算法 哈希算法的特点有 1 输入可以为任意大小的字符串 2 产生固定大小的输出 3 可以在合理的时间内算出输出值 若要满足密
  • 二叉树结构的建立与遍历

    实验项目 1 编写建立二叉树的二叉链表存储结构 左右链表示 的程序 并以适当的形式显示和保存二叉树 2 完成二叉树的7种遍历操作 3 给定一个二叉树 编写算法完成下列应用 1 判断其是否为完全二叉树 2 求二叉树中任意两个结点的公共祖先 输
  • 插入排序超详解释,一看就懂

    目录 一 插入排序的相关概念 1 基本思想 2 基本操作 有序插入 二 插入排序的种类 三 直接插入排序 1 直接插入排序的过程 顺序查找法查找插入位置 2 使用 哨兵 直接插入排序 四 直接插入排序算法描述 五 折半插入排序 1 查找插入
  • 基数排序代码实现

    详情请看排序总结 传送门 https blog csdn net m0 52711790 article details 121914543 基数排序的知识点我就不贴出来 相信都能搜到对应概念解释 下面就直接上代码 代码解释其实也很清晰了
  • 雪糕的最大数量 排序+贪心

    雪糕的最大数量 雪糕的最大数量 题目描述 样例 数据范围 思路 代码 题目描述 夏日炎炎 小男孩 Tony 想买一些雪糕消消暑 商店中新到 n 支雪糕 用长度为 n 的数组 costs 表示雪糕的定价 其中 costs i 表示第 i 支雪
  • Leetcode1094. 拼车

    Every day a Leetcode 题目来源 1094 拼车 解法1 差分数组 对于本题 设 a i 表示车行驶到位置 i 时车上的人数 我们需要判断是否所有 a i 都不超过 capacity trips i 相当于把 a 中下标从
  • 【数据结构入门精讲 | 第二篇】一文讲清算法复杂度

    上篇文章中我们引入了算法 数据结构 数据类型等概念 而要想衡量一个算法与数据结构是否为优质的 就需要一个衡量标准 这个衡量标准也是在我们实现一个好的算法时要遵循的原则 目录 基本概念 渐进性态 渐进性态数学表征 算法复杂度的运算 顺序搜索算
  • 最大流-Dinic算法,原理详解,四大优化,详细代码

    文章目录 零 前言 一 概念回顾 可略过 1 1流网络 1 2流 1 3最大流 1 4残留网络 1 5增广路

随机推荐