拓扑排序与关键路径的搜寻:
一种排序·算法,据说是一家公司发明的,还靠着拓扑排序挤进了50强= =
这种算法常用便于生活= =,比如说,你要做饭,烧水的同时又可以去洗菜,煮饭的同时又可以炒菜,但炒菜之前得先洗菜,切菜。。。。。拓扑排序就可以算出完成做菜任务的顺序= =。
(学会了就可以当家庭主妇了,嘿嘿)
这里先解释
度:指和该顶点相关联的边数。
入度:指有向图中某点作为图中边的终点的次数之和。
出度:以某顶点为弧头,终止于该顶点的弧的数目称为该顶点的入度。
例子:
0的入度为2,出度为2,度为4;
AOV网(Activity On Vertex network):以顶点表示活动,有向边表示活动之间的优先关系, 则称这样的有向图为AOV网(顶点活动图)
(AOV网一定是有向图,且一定是有向无环图!)
~~~~~~~~~~~~
所以可以用来判断环
~~~~~~~~~~~~
拓扑排序要用到栈的相关知识~
算法主要如下:
1.图丶栈 储存
2.选入度为0的(顶点)输出
3.删除相关边,和此顶点
4.重复2.3.直到不存在入度为0的顶点为止
#include<string.h>
#include<iostream>
#include<stdio.h>
using namespace std;
#define MAX 100
void top_sort(int map[MAX][MAX],int indgr[MAX],int n){
int i,j,k;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(indgr[j]==0){
indgr[j]--;
cout<<j<<endl;
for(k=0;k<n;k++)
if(map[j][k]==1)
indgr[k]--;
break;
}
}
int main(){
int n,m;
while(scanf("%d %d",&n,&m)&&n!=0){
int i;
int x,y;
int map[MAX][MAX];
int indgr[MAX];
memset(map,0,sizeof(map));
memset(indgr,0,sizeof(indgr));
for(i=0;i<n;i++){
scanf("%d %d",&x,&y);
if(!map[x][y]){
map[x][y]=1;
indgr[y]++;
}
}
top_sort(map,indgr,m);
}
return 0;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
下面是关键路径了~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AOE网(Activity On Edge):用顶点表示事件,弧表示活动,边上的权值表示该活动持续的时间
路径长度——路径上各活动持续时间之和
关键路径——路径长度最长的路径
关键活动——关键路径上的活动
Ve[j]——表示事件V[j]的最早发生时间
Vl[j]——表示事件V[j]的最迟发生时间
e[i]——表示活动a[i]的最早开始时间
l[i]——表示活动a[i]的最迟开始时间
l[i]-e[i]——表示完成活动a[i]的时间余量(如果==0,那这是关键活动)
主要代码:(输入的数据用邻接表储存,拓扑排序求Ve,逆拓扑求Vl)
V[1]=0;
Ve[j]=max{Ve[i]+dut(
#include<stdio.h>
#include<string.h>
int n,m,l=0,r=0;
int w[1001][1001],prev[1001],queue[1001];
int Time[1001],Pos[1001],path[1001];
int init(void){
int i,a,b,c;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++){
scanf("%d%d%d",&a,&b,&c);
w[a][b]=c;
prev[b]++;
}
}
inline void Newq(int v){
r++;
queue[r]=v;
}
inline void Del(int v){
int i;
for(i=1;i<=n;i++)
if(w[v][i]){
prev[i]--;
if(!prev[i])
Newq(i);
}
}
int topo(void){
for(int i=1;i<=n;i++)
if(!prev[i])
Newq(i);
while(r<n){
l++;
Del(queue[l]);
}
}
int crucialpath(void){
int i,j;
memset(Time,0,sizeof(Time));
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if((w[j][queue[i]])&&(Time[j]+w[j][queue[i]]>Time[queue[i]])){
Time[queue[i]]=Time[j]+w[j][queue[i]];
Pos[queue[i]]=j;
}
}
int print(void){
printf("%d\n",Time[n]);
int i=n,k=0;
while(i!=1){
k++;
path[k]=i;
}
for(i=k;i>1;i--)
printf("%d ",path[i]);
printf("%d\n",path[1]);
}
int main(){
init();
topo();
crucialpath();
print();
return 0;
}
请大神补充(///^///).