工程安排(拓扑排序)

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
  • 白盒测试相关的一些知识

    在白盒测试中 可以使用各种测试方法进行测试 下面这篇文章 可能比较枯燥 如果不乐意读 可以先收藏 如果在你的工作中真遇到白盒测试的话 可以回过头再来看看 还是值得读一读 一般来说 白盒测试时要考虑以下5个问题 1 测试中尽量先用自动化工具来
  • 一文弄懂循环链表、双向链表、静态链表

    循环链表 双向链表 静态链表 三遍定律 理解了单链表本文的理解易如反掌 单链表请点击这里 理解了单链表本文的理解易如反掌 单链表请点击这里 理解了单链表本文的理解易如反掌 单链表请点击这里 1 循环链表 将单链表中终端结点的指针端由空指针改
  • 第二十八节、基于深度学习的目标检测算法的综述(附代码,并附有一些算法英文翻译文章链接))...

    在前面几节中 我们已经介绍了什么是目标检测 以及如何进行目标检测 还提及了滑动窗口 bounding box 以及IOU 非极大值抑制等概念 这里将会综述一下当前目标检测的研究成果 并对几个经典的目标检测算法进行概述 本文内容来自基于深度学
  • Qt——用于表格QTableView的模型

    如果想使用表格来呈现数据 Qt提供了一个方便的部件QTableWidget 但是直接用它实现一些功能可能比较困难 这里将介绍一种强大 灵活的方式来操作表格 一 模型 视图架构 在这个架构中 模型用于存储数据 视图用于呈现数据 除此之外 还有
  • 微软2013暑假实习生笔试题

    自己mark一下 以作后备 下面提交原文链接 原文博客 部分题目答案不确定 会持续更新 1 Which of the following calling convention s support s supportvariable leng
  • 如何根据链表节点数据大小对链表节点进行排序

    对链表排序有两种方法 1 比较了两个节点的大小后 对指针进行改变 从而交换节点的顺序 2 比较了两个节点的大小后 只交换数据域 而不改变指针 从而交换节点的顺序 第二种办法比较简单 本文主要对第二种方法进行讲解 链表节点排序算法 采用 冒泡
  • 数据结构——计算节点个数和二叉树高度(C语言版)

    摘自 数据结构 计算节点个数和二叉树高度 C语言版 作者 正弦定理 发布时间 2020 12 12 23 27 09 网址 https blog csdn net chinesekobe article details 111086664
  • 4Sum

    Given an array S of n integers are there elements a b c and d in S such that a b c d target Find all unique quadruplets
  • 堆栈01--用两个栈实现队列

    堆栈01 用两个栈实现队列 jz05 题目概述 解析 参考答案 注意事项 说明 题目概述 算法说明 用两个栈来实现一个队列 完成队列的Push和Pop操作 队列中的元素为int类型 测试用例 队列先进先出 输入 1 2 输出 1 2 解析
  • 浮生六记

    浮生六记 目录 浮生六记卷一 闺房记乐 002 浮生六记卷二 闲情记趣 015 浮生六记卷三 坎坷记愁 022 浮生六记卷四 浪游记快 034 浮生六记 2 浮生六记卷一 闺房记乐 余生乾隆癸未冬十一月二十有二日 正值太平盛世 且在 衣冠之
  • 数理统计知识整理——回归分析与方差分析

    题记 时值我的北科研究生第一年下 选学 统计优化 课程 备考促学 成此笔记 以谨记 1 线性回归 1 1 原理分析 要研究最大积雪深度x与灌溉面积y之间的关系 测试得到近10年的数据如下表 使用线性回归的方法可以估计x与y之间的线性关系 线
  • 时间复杂度+常见复杂度解释

    前言 算法的效率 虽然计算机能快速的完成运算处理 但实际上 它也需要根据输入数据的大小和算法效率来消耗一定的处理器资源 要想编写出能高效运行的程序 我们就需要考虑到算法的效率 算法的效率主要由以下两个复杂度来评估 时间复杂度 评估执行程序所
  • 索引优化之Explain 及慢查询日志

    索引 本质是数据结构 简单理解为 排好序的快速查找数据结构 以索引文件的形式存储在磁盘中 目的 提高数据查询的效率 优化查询性能 就像书的目录一样 优势 提高检索效率 降低IO成本 排好序的表 降低CPU的消耗劣势 索引实际也是一张表 该表
  • Leetcode2661. 找出叠涂元素

    Every day a Leetcode 题目来源 2661 找出叠涂元素 解法1 哈希 题目很绕 理解题意后就很简单 由于矩阵 mat 中每一个元素都不同 并且都在数组 arr 中 所以首先我们用一个哈希表 hash 来存储 mat 中每
  • 数组实现循环队列(增设队列大小size)

    目录 一 前言 1 如何实现循环 2 如何判断队列为空 3 如何判断队列为满 二 循环队列的结构定义 三 循环队列的创建及其初始化 四 入队 五 出队 六 取队头元素 七 取队尾元素 八 循环队列判空 九 循环队列判满 十 循环队列销毁 一
  • 【数据结构】双链表的定义和操作

    目录 1 双链表的定义 2 双链表的创建和初始化 3 双链表的插入节点操作 4 双链表的删除节点操作 5 双链表的查找节点操作 6 双链表的更新节点操作 7 完整代码 嗨 我是 Filotimo 很高兴与大家相识 希望我的博客能对你有所帮助
  • C++ AVL树(四种旋转,插入)

    C AVL树 四种旋转 插入 一 AVL树的概念及性质 二 我们要实现的大致框架 1 AVL树的节点定义 2 AVL树的大致框架 三 插入 1 插入逻辑跟BST相同的那一部分 2 修改平衡因子
  • C++ AVL树(四种旋转,插入)

    C AVL树 四种旋转 插入 一 AVL树的概念及性质 二 我们要实现的大致框架 1 AVL树的节点定义 2 AVL树的大致框架 三 插入 1 插入逻辑跟BST相同的那一部分 2 修改平衡因子
  • 最大流-Dinic算法,原理详解,四大优化,详细代码

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

随机推荐