求AOE网的关键路径

问题描述以及算法的思想网上有许多,为了省事就不写了,给几个链接如果不太了解的可以参考一下。

http://baike.baidu.com/view/288224.htm

http://blog.163.com/zhoumhan_0351/blog/static/3995422720098236028304/

这里需要说明一下,这一次我所采用的数据结构是邻接表了,本来想接着用矩阵的,但是怕老是用矩阵,以后就把邻接表给忘记了,所以这次就拿邻接表练了练手。

还有就是,在求取关键路径之前,为了一般性,还要对网络进行拓扑排序的,所以这里重新写了一遍拓扑排序,当然也挺好,又用邻接表实现了一下。

这个程序说实话写的可磨叽了,首要原因是F(1111)节的影响,有点心浮气躁的。当然,技术方面还是自己比较菜,所以老犯些低级错误,在下面会有总结。

参考代码:

#include<iostream>
#include<fstream>
using namespace std;

struct Edge
{
	int node;
	int cost;
	Edge *next;
	Edge(int n,int c,Edge *e=NULL){node=n;cost=c;next=e;}
};

struct Head
{
	Edge *top;
	Head(Edge *t=NULL){top=t;}
};

class Graph
{
public:
	int size;
	Head *head;
	int *order;
	Graph();
	~Graph();
	bool topoOrder();
	void criticalPath();
	void out()
	{
		cout<<"TopoOrder is:"<<endl;
		for(int i=1;i<size+1;i++)
		{
			cout<<order[i]<<"\t";
		}
		cout<<endl;
	}
};
Graph::Graph()
{
	ifstream in;
	in.open("graph.txt",ios::in);
	in>>size;
	head=new Head[size+1];
	order=new int[size+1];
	int f,t,c;
	in>>f>>t>>c;
	while(f!=0&&t!=0&&c!=0)
	{
		head[f].top=new Edge(t,c,head[f].top);
		in>>f>>t>>c;
	}
}
Graph::~Graph()
{
	for(int i=1;i<size+1;i++)
	{
		Edge *e1=head[i].top;
		while(e1!=NULL)
		{
			head[i].top=e1->next;
			delete e1;
			e1=head[i].top;
		}
	}
	delete[] order;
	delete[] head;
}
bool Graph::topoOrder()
{
	
	int *count=new int[size+1];
	Edge *e=NULL;
	for(int i=1;i<size+1;i++)
	{
		count[i]=0;
	}
	for(int i=1;i<size+1;i++)
	{
		e=head[i].top;
		while(e!=NULL)
		{
			count[e->node]++;
			e=e->next;
		}
	}
	
	int top=-1;
	for(int i=1;i<size+1;i++)
	{
		if(count[i]==0)
		{
			count[i]=top;
			top=i;
		}
	}
	for(int i=1;i<size+1;i++)
	{
		if(top==-1)
		{
			cout<<"Cycle!"<<endl;
			return false;
		}
		int j=top;
		top=count[top];
		order[i]=j;
		e=head[j].top;
		while(e!=NULL)
		{
			if(--count[e->node]==0)
			{
				count[e->node]=top;
				top=e->node;
			}
			e=e->next;
		}
	}
	return true;
}
void Graph::criticalPath()
{
	int *ve=new int[size+1];
	int *vl=new int[size+1];
	for(int i=1;i<size+1;i++)
	{
		ve[i]=0;
	}
	for(int i=1;i<size;i++)
	{
		int j=order[i];
		Edge *e=head[j].top;
		while(e!=NULL)
		{
			int k=e->node;
			if(ve[j]+e->cost>ve[k])
			{
				ve[k]=ve[j]+e->cost;
			}
			e=e->next;
		}
	}
	for(int i=1;i<size+1;i++)
	{
		vl[i]=ve[order[size]];
	}
	for(int i=size-1;i>0;i--)
	{
		int j=order[i];
		Edge *e=head[j].top;
		while(e!=NULL)
		{
			int k=e->node;
			if(vl[k]-e->cost<vl[j])
			{
				vl[j]=vl[k]-e->cost;
			}
			e=e->next;
		}
	}
	for(int i=1;i<size+1;i++)
	{
		int j=order[i];
		Edge *e=head[j].top;
		while(e!=NULL)
		{
			int k=e->node;
			if(ve[j]==vl[k]-e->cost)
			{
				cout<<"("<<j<<","<<k<<")"<<endl;
			}
			e=e->next;
		}
	}
	delete[] ve;
	delete[] vl;
}
int main()
{
	Graph g;
	if(g.topoOrder())
	{
		g.out();
		g.criticalPath();
	}
	return 0;
}


Coding过程中出现的问题:

1.下面这段代码的最后一行给忘记了,造成了死循环,结果可想而知,几G内存一会就没了...

while(f!=0&&t!=0&&c!=0)
	{
		head[f].top=new Edge(t,c,head[f].top);
		in>>f>>t>>c;
	}
2.漏了这一段,标志变量一定要对初始状态进行初始化!!!

for(int i=1;i<size+1;i++)
	{
		count[i]=0;
	}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值