人们用一种有向图来表示这些工程、计划等,在这种有向图中,顶点表示活动,有向边表示活动的优先关系,这种用顶点表示活动,用弧来表示活动间的优先关系的有向图叫做顶点表示活动的网络(Actire On Vertices)简称为AOV网。在AOV网中不应该出现有向环。
通常,在AOV网中,将所有活动排列成一个拓扑序列的过程叫做拓扑排序(Topological Sort)。 、、
从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它。
//算法描述
// 0度结点的权为0
// 核心:假设有a->b(b的权=b的权+a的权+1)
// 具体实现有:假设有 b->c;b->d;b->e;结点cde进入队列
// 权越小排序越靠前
//
//在编写的代码的过程中,犯了个大错误
//void shenqing(int **&T,int* &dui);//申请动态空间,错误:没有使用引用;导致申请的空间无效
测试数据
6 8
0 1
0 2
0 3
2 4
2 1
3 4
5 3
5 4
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int v;//////点数目
int edge;///边数目
int dui_front=0;//队头
int dui_rear=0;//队尾//////头有数据,尾无数据
int** draw();//绘图,有向无环图
void shenqing(int **&T,int* &dui);//申请动态空间
void tuopusort(int** a,int** T,int* dui);//拓扑排序
void SelectSort(int **arr,int length);
int main(int argc, char const *argv[])
{
int**a=draw();//图
int **T;//存放点以及其对应的权,T是n行2列的数组,它的第二列放的权
int* dui;//队列
shenqing(T,dui);
tuopusort(a,T,dui);
SelectSort(T,v);
for (int i = 0; i < v; ++i)
{
cout<<T[i][0]<<" "<<T[i][1]<<endl;
}
//------------------------------------------------------------------------//
//释放空间
delete []a;
delete []T;
delete []dui;
return 0;
}
int** draw()//绘图
{
int i,j;
cin>>v>>edge;///输入点数目和边数目
int **a=new int*[v];
for ( i = 0; i < v; ++i)
a[i]=new int[v];
for ( i = 0; i < v; ++i)
for ( j = 0; j < v; ++j)
a[i][j]=0;
int spot1,spot2;
for ( i = 0; i < edge; ++i)
{
cin>>spot1>>spot2;
a[spot1][spot2]=1;
}
///-------------------------------------------------------------///
cout<<"\n";
for ( i = 0; i < v; ++i)
{
for ( j = 0; j < v; ++j)
{
cout<<a[i][j]<<" ";
}
cout<<"\n";
}
cout<<"\n";
return a;
}
void shenqing(int **&T,int* &dui)//引用
{
int i;
T=new int*[v];
for ( i = 0; i < v; ++i)
T[i]=new int[2];
for ( i = 0; i < v; ++i)
{
T[i][0]=i; T[i][1]=0;
}
dui=new int[v];
}
void tuopusort(int** a,int** T,int* dui)
{
int i,j,temp;
//----------------------------------------------------//
////获取0入度结点,放入队列中
int panduan=0;
for ( i = 0; i < v; ++i)
{
for ( j = 0; j < v; ++j)//计算列
{
if(a[j][i]==1)panduan=1;
}
if (panduan==0)//0入度的结点
{
temp=dui_rear++ % v;
dui[temp]=i;
}
panduan=0;
}
//----------------------------------------------------//
if (dui_front==dui_rear)///无0入度的结点,及有环
{
cout<<"有环";
exit(1);
}
//----------------------------------------------------//
int tempdui;
while(true)
{
tempdui = dui[dui_front++ % v];
for ( i = 0; i < v; ++i)
{
if (a[tempdui][i]==1)
{
T[i][1] += T[tempdui][1] +1;
for ( j = dui_front; j < dui_rear; ++j)
if (i==j)continue;//已经存在结点i了,不能再次加进去了
dui[dui_rear++ % v]=i;
}
}
if (dui_front==dui_rear)
break;//处理完毕
}
}
void SelectSort(int **arr,int length){
int min,temp,temp2;
for(int i=0;i<length-1;i++)
{
min=i;
for(int j=i+1;j<length;j++)
{
if(arr[min][1]>arr[j][1])
min=j;
}
if(i<min)/////////下面的三条语句实现交换
{
temp=arr[i][0]; temp2=arr[i][1];
arr[i][0]=arr[min][0]; arr[i][1]=arr[min][1];
arr[min][0]=temp; arr[min][1]=temp2;
}
}
}