1.1图的数组表示法

//无向图
#include<stdio.h>  
#include<stdlib.h>  
#define INFINITY 999  
#define MAX_VERTEX 20  
typedef char VertexType; //顶点类型  
typedef int EdgeType; //边上的权值类型  
typedef int Boolean;

Boolean visited[MAX_VERTEX];
typedef struct
{
    VertexType vexs[MAX_VERTEX];//顶点表     
    EdgeType arc[MAX_VERTEX][MAX_VERTEX];
    int vexnum, arcnum;//顶点数和边数  
}MGraph;

void Creat(MGraph *G)
{
    int i, j, k, w;
    printf("输入顶点数和边数\n");
    scanf("%d %d", &G->vexnum, &G->arcnum);
    printf("输入顶点信息\n");
    for (i = 0; i < G->vexnum; i++) //输入顶点信息,简历顶点表  
    {
        getchar();
        scanf("%c", &G->vexs[i]);
    }
    for (i = 0; i<G->vexnum; i++)//邻接矩阵初始化  
    for (j = 0; j<G->vexnum; j++)
        G->arc[i][j] = INFINITY;
    for (k = 0; k<G->arcnum; k++)//读入arcnum条边,建立邻接矩阵  
    {
        printf("输入边(vi,vj)的i j 权值w\n");
        scanf("%d %d %d", &i, &j, &w);
        G->arc[i][j] = w;
        G->arc[j][i] = G->arc[i][j];//无向图,邻接矩阵对称  
    }
}
void DFS(MGraph G, int i)
{
    int j;
    visited[i] = 1;
    printf(" %c ", G.vexs[i]);
    for (j = 0; j < G.vexnum;j++)
    if (G.arc[i][j] == 1 && visited[j] == 0)
        DFS(G, j);
}
void DFSTraverse(MGraph G)
{
    int i;
    for (i = 0; i < G.vexnum; i++)
        visited[i] = 0;
    for (i = 0; i < G.vexnum;i++)
    if (visited[i] == 0)
        DFS(G, i);
}
int main()
{
    MGraph G;
    Creat(&G);
    DFSTraverse(G);

    return 0;
}

1.2邻接矩阵

//无向图
#include<stdio.h>
#include<stdlib.h>
#define MAXVEX 20
typedef char VertexType;//顶点类型
typedef int EdgeType; //边上的权值类型
typedef int Boolean;
Boolean visited[MAXVEX];
typedef struct ArcNode //编表结点
{
    int adjevx; //该弧所指向的顶点位置
    EdgeType weight;//存储权值
    struct ArcNode *nextarc; //指向下一条弧的指针
}ArcNode;
typedef struct //顶点表结点
{
    VertexType data;//顶点信息
    ArcNode *firstarc;//边表头指针
}VNode, AdjList[MAXVEX];
typedef struct
{
    AdjList vertices;
    int vexnum, arcnum;
}ALGraph;
void Creat(ALGraph *G)
{
    int i, j, k;
    ArcNode *e;
    printf("输入顶点数 边数:\n");
    scanf("%d %d", &G->vexnum, &G->arcnum);
    printf("输入顶点信息\n");
    for (i = 0; i < G->vexnum; i++)
    {
        getchar();
        scanf("%c", &G->vertices[i].data);
        G->vertices[i].firstarc = NULL;//将边表置为空表
    }
    for (k = 0; k < G->arcnum; k++)//建立边表
    {
        printf("输入边(v1,v2)的顶点下标\n");
        scanf("%d %d", &i, &j);
        //头插法
        e = (ArcNode *)malloc(sizeof(ArcNode));
        e->adjevx = j;//顶点下标为j
        e->nextarc = G->vertices[i].firstarc;
        G->vertices[i].firstarc = e;

        //无向图,一条边对应两个结点
        e = (ArcNode *)malloc(sizeof(ArcNode));
        e->adjevx = i;
        e->nextarc = G->vertices[j].firstarc;
        G->vertices[j].firstarc = e;
    }
}
void DFS(ALGraph G, int i)
{
    ArcNode *p;
    visited[i] = 1;
    printf(" %c ", G.vertices[i].data);
    p = G.vertices[i].firstarc;
    while (p)
    {
        if (visited[p->adjevx] == 0)
            DFS(G, p->adjevx);
        p = p->nextarc;
    }
}
void DFSTraverse(ALGraph G)
{
    int i;
    for (i = 0; i < G.vexnum; i++)
        visited[i] = 0;
    for (i = 0; i < G.vexnum;i++)
    if (visited[i] == 0)
        DFS(G, i);

}



2.1拓扑排序

#include<stdio.h>
#include<stdlib.h>
#include"stack.h"
#define Status int
#define ERROR 0
#define OK 1
typedef struct ArcNode
{
	int adjvex;//顶点下标
	struct ArcNode *nextarc;
}ArcNode;
typedef struct VNode
{
	char data;
	ArcNode *firstarc;
}VNode,Adjlist[20];
typedef struct
{
	Adjlist vertices;
	int vexnum, arcnum;//当前的的顶点数和弧数
}AlGraph;

void Creat(AlGraph *G)
{//建立邻接表
	int i, j, k;
	ArcNode *e;
	printf("输入顶点数 边数:\n");
	scanf("%d %d", &G->vexnum, &G->arcnum);
	for (i = 0; i < G->vexnum; i++)
	{
		printf("输入顶点信息\n");
		getchar();
		scanf("%c", &G->vertices[i].data);
		G->vertices[i].firstarc = NULL;
	}
	for (k = 0; k < G->arcnum; k++)//建立边表 
	{
		printf("第%d条边顶点下标\n",k+1);
		scanf("%d %d", &i, &j);
		//头插法建立单向邻接表  
		e = (ArcNode *)malloc(sizeof(ArcNode));
		e->adjvex = j;
		e->nextarc = G->vertices[i].firstarc;
		G->vertices[i].firstarc = e;
	}
}
void FindInDegree(AlGraph *G, int *InDegree)
{//求顶点入度
	int i;
	ArcNode *p;
	for (i = 0; i < G->vexnum; i++)
	{//顶点入度初始化
		InDegree[i] = 0;
	}
	for (i = 0; i < G->vexnum; i++)
	{
		p = G->vertices[i].firstarc;
		while (p)
		{
			InDegree[p->adjvex]++;
			p = p->nextarc;
		}
	}
}

void TopologicalSort(AlGraph *G,SqStack S)
{//求拓扑排序
	int indegree[20],count=1,i,k;
	//保存顶点入度数组,count为对出栈的顶点计数
	char a[20];//保存拓扑序列的数组
	ArcNode *p;
	FindInDegree(G, indegree);

	for (i = 0; i < G->vexnum;i++)
	if (!indegree[i])
		Push(&S, i);//入度为0者进栈
	while (S.top>-1)//栈不空
	{
		Pop(&S, &i);
		a[count++] = G->vertices[i].data;
		for (p = G->vertices[i].firstarc; p; p = p->nextarc)
		{
			indegree[p->adjvex]--;
			if (!(indegree[p->adjvex]))
				Push(&S, p->adjvex);
		}
	}//while
	if (count < G->vexnum)
	{
		printf("error"); return ERROR;
	}
	else
	{
		printf("拓扑序列为:");
		for (i = 1; i <count-1; i++)
			printf("%c->",a[i]);
		printf("%c", a[i]);
		return OK;
	}
	}

int main()
{
	AlGraph G;
	SqStack S;
	Creat(&G);
	InitStack(&S);
	TopologicalSort(&G, S);
}

//stack.h

#include<stdlib.h>  
#include<stdio.h>
#define MAX 20  

typedef struct SqStack
{
	int elem[MAX];
	int top;//栈顶指针  
}SqStack;
int InitStack(SqStack *S)
{
	S->top = -1; 
	return 1;
}
int Push(SqStack *S,int x)
{
	//在栈顶插入新元素x,返回1表示入栈成功,返回0表示失败  
	int n;
	if (S->top == MAX - 1){ printf("栈满不能入栈\n"); return 0; }
	else
	{
		
			S->top++;
			S->elem[S->top] = x;
		return 1;
	}
}
int Get_SqStack(SqStack *S, int *e)
{
	//用e栈顶元素,成功返回1,失败返回0  
	if (S->top == -1){ printf("栈是空的"); return 0; }
	else
		*e = S->elem[S->top];
	return 1;
}
int Pop(SqStack *S, int *e)
{
	//删除栈顶元素,用tmp返回其值,返回值为1表示出栈成功,为0表示出栈失败  
	if (S->top == -1){ printf("栈是空的"); return 0; }
	else (*e = S->elem[S->top]);
	S->top--;
	return 1;
}
void outline(SqStack *S)
{
	for (int i = S->top; i >= 0; i--)
		printf("%2d", S->elem[i]);
}

2.2关键路径

#include<stdio.h>
#include<stdlib.h>
#include"stack.h"
#define Status int
#define ERROR 0
#define OK 1
typedef struct ArcNode
{
	int adjvex;//顶点下标
	int weight;
	struct ArcNode *nextarc;
}ArcNode;
typedef struct VNode
{
	char data;
	ArcNode *firstarc;
}VNode,Adjlist[20];
typedef struct
{
	Adjlist vertices;
	int vexnum, arcnum;//当前的的顶点数和弧数
}AlGraph;

void Creat(AlGraph *G)
{//建立邻接表
	int i, j, k,w;
	ArcNode *e;
	printf("输入顶点数 边数:\n");
	scanf("%d %d", &G->vexnum, &G->arcnum);
	for (i = 0; i < G->vexnum; i++)
	{
		printf("输入顶点信息\n");
		getchar();
		scanf("%c", &G->vertices[i].data);
		G->vertices[i].firstarc = NULL;
	}
	for (k = 0; k < G->arcnum; k++)//建立边表 
	{
		printf("第%d条边的两个顶点下标及权值(空格隔开)\n",k+1);
		scanf("%d %d %d", &i, &j,&w);
		//头插法建立单向邻接表  
		e = (ArcNode *)malloc(sizeof(ArcNode));
		e->adjvex = j;
		e->weight = w;
		e->nextarc = G->vertices[i].firstarc;
		G->vertices[i].firstarc = e;
	}
}
void FindInDegree(AlGraph *G, int *InDegree)
{//求顶点入度
	int i;
	ArcNode *p;
	for (i = 0; i < G->vexnum; i++)
	{//顶点入度初始化
		InDegree[i] = 0;
	}
	for (i = 0; i < G->vexnum; i++)
	{
		p = G->vertices[i].firstarc;
		while (p)
		{
			InDegree[p->adjvex]++;
			p = p->nextarc;
		}
	}
}

int TopologicalSort(AlGraph *G,SqStack S,int *a)
{//求拓扑排序
	int indegree[20],count=0,i;
	//保存顶点入度数组,count为对出栈的顶点计数
	ArcNode *p;
	FindInDegree(G, indegree);
	for (i = 0; i < G->vexnum;i++)
	if (!indegree[i])
		Push(&S, i);//入度为0者进栈
	while (S.top>-1)//栈不空
	{
		Pop(&S, &i);
		a[count++] = i;
		for (p = G->vertices[i].firstarc; p; p = p->nextarc)
		{
			indegree[p->adjvex]--;
			if (!(indegree[p->adjvex]))
				Push(&S, p->adjvex);
		}
	}//while
	if (count+1 < G->vexnum)
	{
		printf("error"); return ERROR;
	}
	else
	{
		return OK;
	}
}

int CriticalPath(AlGraph *G)
{
	int ve[20], vl[20];//事件的最早和最晚发生时间
	int e[20], l[20];//活动的最早和最晚发生时间
	int a[20];//保存拓扑排序序列顶点下标
	int i,k,j,n=0;
	ArcNode *p;
	SqStack S;
	InitStack(&S);
	TopologicalSort(G, S,a);
	
	for (i = 0; i < G->vexnum; i++)//ve[]置初值
		ve[i] = 0;
 	for (i = 0; i < G->vexnum; i++)//求每个事件的最早发生时间
	{
		k = a[i];
		p = G->vertices[k].firstarc;
		while (p != NULL)
		{//修改顶点k的所有后继结点的最早发生时间
			j = p->adjvex;
			if (ve[j] < ve[k] + p->weight)
				ve[j] = ve[k] + p->weight;
			p = p->nextarc;
		}
	}

	for (i = 0; i < G->vexnum; i++)//vl[]置初值
		vl[i] = ve[G->vexnum-1];
	for (i = G->vexnum - 1; i >= 0; i--)//按逆拓扑排序求每个事件的最晚发生时间
	{
		k = a[i];
		p = G->vertices[k].firstarc;
		while (p != NULL)
		{
			j = p->adjvex;
			if (vl[k]>vl[j]- p->weight)
				vl[k]=vl[j] - p->weight;
			p = p->nextarc;
		}
	}

	printf("\nAOE网关键路径为:");
	for (i = 0; i < G->vexnum; i++)
	{
		p = G->vertices[i].firstarc;
		while (p!=NULL)
		{
			j = p->adjvex;
			e[n] = ve[i];
			l[n] = vl[j] - p->weight;	//活动的最晚发生时间
			if ((e[n] - l[n]) == 0)
				printf("<%c,%c>", G->vertices[i].data, G->vertices[j].data);
			n++;
			p = p->nextarc;
		}
	}
	return 1;
}

int main()
{
	AlGraph G;
	Creat(&G);
	CriticalPath(&G);
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值