拓扑(TOP)排序

今天要讲的是图论之中一个很重要的东西,叫做拓扑排序,又称top排序(下文中使用这个简称),但是我们得先介绍一下AOV网。
如果有想了解官方学术语言的,戳这里。这里,为了方便,我们使用一些简洁的定义,即用顶点表示活动,用边表示活动的先后顺序的有向图。
拓扑排序,是指在AOV网中,把所有的点按照它们的逻辑关系排成一个线性的序列,是每个点的前驱都排在它前面,称之为top序列。方法如下:

  1. 选择一个入度为0的点,给它一个top序号(这个东西相当于存储答案,就是保存的意思,但是为了语言书面化,高大上一点点)。
  2. 删除该点以及它所有的出边。
  3. 重复1、2,直到没有一个入度为0的点。
    检查:若top序列中的点数为总点数,成功top!否则就会有一个圈(环)。
    程序:

用in数组表示每个点的入度个数,用g数组表示任意两个点有无连通(直接的道路),总点数用n表示。

do{
        i++;j=1;
        while(j<=n && in[j])j++;
        if(j>n)break;
        ans[i]=j;in[j]=1;
        for(k=1;k<=n;k++)
            if(g[j][k])
                in[k]--;
    }while(i

现在我们来看一道例题,士兵列队。这是一道裸的top排序,所以只需要套模板就可以了,详情见代码!

using namespace std;
int g[110][110],in[110],ans[110],q[110];
void out(int tail){
    printf("%d",ans[1]);
    for(int i=2;i<=tail;i++)
        printf(" %d",ans[i]);
    puts("");
}
int main(){
    int i,j,k,n,m,a,b;
    scanf("%d",&n);
    while(scanf("%d %d",&a,&b)==2){
        g[a][b]=1;in[b]++;
    }
    i=0;
    do{
        i++;j=1;
        while(j<=n && in[j])j++;
        if(j>n)break;
        ans[i]=j;in[j]=1;
        for(k=1;k<=n;k++)
            if(g[j][k])
                in[k]--;
    }while(iif(in)printf("Impossible\n");
    else out(i);
    return 0;
}

具体的top要和具体问题分析,模板题还是比较少,重点是运用!

你可能感兴趣的:(题解,数据结构,算法,题目,题库)