文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>查找图的关键路径【C/数据结构】

查找图的关键路径【C/数据结构】

时间:2010-05-31  来源:advancing

//《数据结构》课程实习(程序实现采用C语言)//编译运行通过

//题目:

对于给定的一个工程施工图,该图以边为单位从键盘输入,编写能够找出该图的关键路径的程序。

//代码:

 

#include<malloc.h>
#include<stdio.h>

/*用邻接表实现关键路径的求*/
#define MAX 20 /*头结点的最大值*/
#define NUNUM 20

struct node /*邻接点定义*/
{
    int adjvex; /*顶点信息,序号*/
    int dut; /*权值*/
    struct node *next;
};

struct vnode /*头结点定义*/
{
    int vertex; /*顶点信息,序号*/
    int id; /*顶点入度*/
    struct node *link; /*头结点的链域,指向后续邻接点*/
}Adjlist[MAX];

void CreateGraph(struct vnode Adjlist[MAX],int n,int e)/*构建图*/
{
    /*n为顶点数,e为图的边数*/
    int i,j,k,l;
    struct node * p;/*开辟新的邻接点所用的指针类型变量*/


    for(i=1;i<=n;i++)
    {
        /*建立顶点表*/
        printf("\nPlease enter the data of %d(vertex) and ru du (id)",i);
        scanf("%d",&Adjlist[i].vertex);
        scanf("%d",&Adjlist[i].id);
        Adjlist[i].link=NULL;
     }

     for(k=1;k<=e;k++)
     {
        /*邻接表完善*/
        printf("\nEnter bian<Vi,Vj>de i,j and bian shang de quan zhi w:");
        scanf("%d",&i);
        scanf("%d",&j);
        scanf("%d",&l);
        p=(struct node *)malloc(sizeof(struct node));/*生成新的边表结点*/
        p->adjvex=j; /*将邻接点序号赋值给新结点的顶点信息域*/
        p->dut=l; /*权值*/
        p->next=Adjlist[i].link;
        Adjlist[i].link=p; /*将新结点插入到顶点Vi的边表头部*/
     }
}

void CriticalPath(struct vnode Adjlist[MAX],int n)
{
    int i,j,m,front,rear;
    int k=0;

    int ve[NUNUM],vl[NUNUM],e[NUNUM],l[NUNUM];
    int tpord[NUNUM];

    struct node *p;

    for(i=1;i<=n;i++) /*顶点的最早和最迟发生时间,初始化为0*/
    {
        ve[i]=0; /*最早发生时间*/
        vl[i]=0; /*最迟发生时间*/
    }
    front=0; /*关于堆栈所用变量 front(跟随变量,判断是否堆栈中的结点数据是否已经全部操作过)rear的初始化为0*/
    rear=0; /*入栈时所用的变量,与数组tpord相联系*/

    for(i=1;i<=n;i++) /*首先,遍历邻接表的表头,查找入度为0的顶点,并存入堆栈数组tpord中*/
    {
        if(Adjlist[i].id==0)
        {
            rear++;
            tpord[rear]=i; /*头结点入度为0的点入栈,数组tpord[],从低到高的顺序存入*/
        }
    }

    m=0; /*变量初始化,此变量为计数顶点的变量m,其将作为判断图是否有回路使用*/
    while(front!=rear) /*栈不空时*/
    {
        front++; /*从低到高的顺序,去对堆栈进行操作*/
        j=tpord[front];/*每次取一个入度为0的顶点,并对其进行如下操作*/
        m++; /*每取一个结点,对M进行加1操作*/

        p=Adjlist[j].link;/*将结点的指针域传给p*/
        while(p!=NULL)/*即用p对结点的后续结点进行循环操作*/
        {
            k=p->adjvex;/*取一个邻接点信息,序号*/
            Adjlist[k].id=Adjlist[k].id-1; /*并将其邻接点入度减去1*/

            if(ve[j]+p->dut>ve[k])
                ve[k]=ve[j]+p->dut; /*顶点的最早发生时间,即取最大值*/

             if(Adjlist[k].id==0) /*然后判断,若此后续邻接点入度为0,则入栈tpord*/
            {
                rear++;
                tpord[rear]=k; /*在原来数组的基础上进行操作,往上执行*/
            }
            p=p->next;/*对其下一个邻接点进行同样的操作,即入度减1,做最早发生时间的工作,然后判断是否入栈(入度是否为0)*/
        }
    }

    if(m<n) /*n为总结点数,m为遍历时所用的计数器,每遍历一个变量将进行加1操作*/
    {
      printf("\nWang zhong you hui lu !Cannot tuo pu pai xu!");/*图中是否有回路*/
      return;
    }

    for(i=1;i<=n;i++)
        vl[i]=ve[i]; /*把所用结点的最早发生时间数据赋值给最迟发生时间数组*/

    for(i=n-1;i>=1;i--) /*进行逆拓扑排序,从堆栈数据的最高位开始*/
    {
        j=tpord[i]; /*取结点号*/
        p=Adjlist[j].link; /*取结点的后续邻接点的指针域*/
        while(p!=NULL) /*对此结点的邻接点进行操作*/
        {
            k=p->adjvex; /*取 邻接点信息,即编号*/
            if((vl[k]-p->dut)<vl[j]) /*在活动<j,k>上进行操作,确定事件j的最迟发生时间*/
                vl[j]=vl[k]-p->dut;
             p=p->next; /*对其下一个邻接点进行同样的操作*/
        }
        
    } /*逆拓扑排序结束*/

    i=0; /*循环判断确定 每个结点的最早发生时间 和最迟发生时间是否相等*/
    for(j=1;j<=n;j++)
    {
        p=Adjlist[j].link;/*取头结点的邻接点的指针域,赋值给p*/
        while(p!=NULL)
        {
            k=p->adjvex; /*获得邻接点的序号,或位置*/
            i++; /*i++操作*/

            e[i]=ve[j]; /*事件j的最早发生时间就是其后活动i的最早发生时间*/
            l[i]=vl[k]-p->dut;/*<j--ai--k>活动ai的最迟发生时间=vl[k]-(p->dut)*/

            printf("\n <%d ,%d>:",Adjlist[j].vertex,Adjlist[k].vertex);
            if(l[i]==e[i]) /*判断是否活动ai的最早发生时间=最迟发生时间?若相等,则此活动为关键活动!*/
            {
                printf("is the key acctivity!");
                
            }
            else
            {
                printf("is not the key acctivity!");
          
            }
            p=p->next;
        }
    }
    printf("\nThanks ,BYE!");
}

void main()
{
    int n,e;
    printf("\nPlease enter the data of ding dian shu :");
    scanf("%d",&n);
    printf("\nPlease enter the data of bian shu: ");
    scanf("%d",&e);
   // getchar();

    CreateGraph(Adjlist,n,e);
    CriticalPath(Adjlist,n);
    //getch();

}


相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载