poj1094(拓扑排序)

来源:互联网 发布:spss绘制散点图矩阵 编辑:程序博客网 时间:2024/06/10 21:13

在图论中,拓扑排序(Topological Sorting)是一个有向无环图(DAG, Directed Acyclic Graph)的所有顶点的线性序列。且该序列必须满足下面两个条件:
1、每个顶点出现且只出现一次。
2、若存在一条从顶点 A 到顶点 B 的路径,那么在序列中顶点 A 出现在顶点 B 的前面。
有向无环图(DAG)才有拓扑排序,非DAG图没有拓扑排序一说。
这里写图片描述
它是一个 DAG 图,那么如何写出它的拓扑排序呢?这里说一种比较常用的方法:
1、从 DAG 图中选择一个 没有前驱(即入度为0)的顶点并输出。
2、从图中删除该顶点和所有以它为起点的有向边。
3、重复 1 和 2 直到当前的 DAG 图为空或当前图中不存在无前驱的顶点为止。后一种情况说明有向图中必然存在环。
这里写图片描述
于是,得到拓扑排序后的结果是 { 1, 2, 4, 3, 5 }。
通常,一个有向无环图可以有一个或多个拓扑排序序列。

拓扑排序可以用队列实现,在这道题中,有三种情况,对应着三个答案,1、当前的这几个关系可以进行排序,2、排序过程中发现没有零度点了,则当前的这几个关系给出的图中零度读点出现,无法排序,出现矛盾(就是产生环,拓扑排序针对的是有向无环图);3、当前给的这几个关系形成的图在排序过程中,多个零度点出现,无法选取,输出不能完成排序。
输入一个关系就要判断一次,才26个点,肯定没问题。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<list>#include<queue>using namespace std;int a[30];//储存排序顺序int mp[30][30];//存边的情况int dis[30];//入度int b[30];//临时入度储存int flag = 0;int n,m;//二维加一维数组实现拓扑排序,list和队列也可以实现拓扑排序。void sortgraph(){    int i,j;    for(i = 0;i < n;++i)    {        b[i] = dis[i];    }    /*for(i = 0;i < n;++i)    {        printf("%d ",b[i]);    }    cout<<endl;*/    int pos = 0;    for(i = 0;i < n;++i)//一次拓扑排序    {        int s = 0;        for(j = 0;j < n;++j)        {            if(b[j] == 0)            {                s++;                pos = j;            }        }        //cout<<s<<endl;        if(s == 0) {//有环            flag = 1;            return ;        }        else{            if(s > 1)//无序                flag = -1;        }        a[i] = pos;        b[pos] = -1;        for(j = 0;j < n;++j)        {            if(mp[pos][j]){                --b[j];            }        }    }}int main(){    char s[4]={0};    while(scanf("%d %d",&n,&m)!=EOF)    {        memset(mp,0,sizeof(mp));        memset(a,0,sizeof(a));        memset(b,0,sizeof(b));        memset(dis,0,sizeof(dis));        if(n==0&&m==0) break;        int i,j;        int sign = 0;        for(i = 1;i <= m;++i)        {            scanf("%s",s);            flag = 0;            if(sign) continue;            mp[s[0]-'A'][s[2]-'A']=1;            dis[s[2]-'A']++;            sortgraph();            if(flag == 1){//有环                printf("Inconsistency found after %d relations.\n",i);                sign = 1;            }            if(flag == 0)            {                printf("Sorted sequence determined after %d relations: ",i);                for(j = 0;j < n;++j)                {                    printf("%c",a[j]+'A');                }                printf(".\n");                sign = 1;            }        }        if(flag == -1)//出现多个零度点,无法排序;                printf("Sorted sequence cannot be determined.\n");    }    return 0;}
原创粉丝点击