问题描述以及算法的思想网上有许多,为了省事就不写了,给几个链接如果不太了解的可以参考一下。
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;
}