无圈图 关键路径

《数据结构与算法分析——C语言描述》  第九章


#include"hash.h"
#include"graph.h"
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include"fatal.h"
#include<stack>
#include<float.h>
#include<queue>
#define MAXN 10000



char nameRecord[MAXN][100];
int vexNum = 0;//点的个数计数器
Graph g1;//原来的图
Graph g2;//倒过来的的图

void readGraph() {
	HashTable hash_StrToNum = initializeTable_hash(5);//初始化一个哈希表
	g1 = initialize_Graph(5);//初始化一个邻接图
	g2 = initialize_Graph(5);
	char i_name[100];
	char j_name[100];
	int i, j;//点i,点
	double weight;//权
	while (scanf("%s%s%lf", i_name, j_name, &weight) == 3) {//输入两个点的名字,和他们之间的权,成功读入的话进入循环
		if (!isExist(i_name, hash_StrToNum)) {//查看曾经是否输入了点i,在O(1)内迅速找出
											  //点i第一次出现
			i = vexNum;//给点i分配图的下标
			strcpy(nameRecord[vexNum], i_name);//复制到名字记录中
			hash_StrToNum = insert_hash(i_name, vexNum, hash_StrToNum);//插入到哈希表中,O(1)完成
			vexNum++;//计数器增加
		}
		else {
			//以前出现过点i
			i = map_hash(i_name, hash_StrToNum);//O(1)内迅速获取点i的下标
		}
		if (!isExist(j_name, hash_StrToNum)) {
			j = vexNum;
			strcpy(nameRecord[vexNum], j_name);
			hash_StrToNum = insert_hash(j_name, vexNum, hash_StrToNum);
			vexNum++;
		}
		else {
			j = map_hash(j_name, hash_StrToNum);
		}
		insertEdge(i, j, weight, g1);//在图中插入边
		insertEdge(j, i, weight, g2);//反过来插入到另一个图中,关键路径的时候要倒过来
	}
	destroyTable_hash(hash_StrToNum);
}

void printGraph(Graph g) {
	if (g) {
		for (int i = 0; i < vexNum; i++) {//给所有点来一个遍历
			EdgeNodePtr p = getEdgeNodePtr(i, g);//获取邻接的点
			printf("indegree:%d ", indegree(i, g));
			while (p) {
				printf("(%s,%s)%g ", nameRecord[i], nameRecord[getVex(p)], getWeight(p));
				p = advance(p);//获取下一个节点
				printf("\n");
			}
		}
	}
	else {
		Error("EMPTY GRAPH");
	}
}


struct TableEntry {
	double ec;
	double lc;
};

typedef struct TableEntry* Table;//数组

Table t;

std::stack<int> topsort() {
	int counter = 0;
	Vertex v, w;
	std::queue<int> q;
	int *indegree = indegreeArray(g1, vexNum);
	std::stack<int> topNumStack;
	for (int i = 0; i < vexNum; i++) {
		t[i].ec = 0;
	}
	for (int i = 0; i < vexNum; i++) {
		if (indegree[i] == 0)
			q.push(i);
	}
	while (!q.empty()) {
		v = q.front();
		q.pop();
		topNumStack.push(counter++);
		EdgeNodePtr adjVexptr = getEdgeNodePtr(v, g1);
		while (adjVexptr) {
			w = getVex(adjVexptr);
			indegree[w]--;
			if (indegree[w] == 0) {
				q.push(w);
			}
			if (t[v].ec + getWeight(adjVexptr)>t[w].ec) 				{
				t[w].ec = t[v].ec + getWeight(adjVexptr);
			}
			adjVexptr = advance(adjVexptr);
		}

	}
	if (counter != vexNum) {
		Error("has cycle");
	}
	return topNumStack;
}

void criticalPath() {
	std::stack<int> topStack= topsort();
	for (int i = 0; i < vexNum; i++) {
		t[i].lc = t[topStack.top()].ec;
	}
	while (!topStack.empty()) {
		Vertex v = topStack.top();
		topStack.pop();
		EdgeNodePtr adjVexptr = getEdgeNodePtr(v, g2);
		while (adjVexptr) {
			Vertex w = getVex(adjVexptr);
			if (t[v].lc - getWeight(adjVexptr) < t[w].lc) 				{
				t[w].lc = t[v].lc - getWeight(adjVexptr);
			}
			adjVexptr = advance(adjVexptr);
		}
	}
	
	for (int i = 0; i < vexNum; i++) 		{
		if (t[i].ec == t[i].lc)
			printf("%s\n", nameRecord[i]);
	}
}



int main() {
	freopen("filein.txt", "r", stdin);
	readGraph();
	t = (Table)malloc(sizeof(struct TableEntry)*vexNum);
	criticalPath();
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值