poj 1094 && NYOJ 349 Sorting It All Out 拓扑排序 经典

来源:互联网 发布:ubuntu 14.04 安装教程 编辑:程序博客网 时间:2024/05/18 02:07
题题意明确,就是给定一组字母的大小关系判断他们是否能组成唯一的拓扑序列。是典型的拓扑排序,但输出格式上确有三种形式:

   1.该字母序列有序,并依次输出;

   2.该序列不能判断是否有序;

   3.该序列字母次序之间有矛盾,即有环存在。

     而这三种形式的判断是有顺序的:先判断是否有环(3),再判断是否有序(1),最后才能判断是否能得出结果(2)注意:对于(2)必须遍历完整个图,而(1)和(3)一旦得出结果,对后面的输入就不用做处理了。

代码如下:

#include<stdio.h>#include<string.h>int map[27][27],indegree[27],q[27];int TopoSort(int n) //拓扑排序{    int c=0,temp[27],loc,m,flag=1,i,j;  ////flag=1:有序 flag=-1:不确定    for(i=1;i<=n;i++)        temp[i]=indegree[i];    for(i=1;i<=n;i++)    {        m=0;        for(j=1;j<=n;j++)            if(temp[j]==0) { m++; loc=j; }  //查找入度为零的顶点个数        if(m==0) return 0;  //有环        if(m>1) flag=-1;  // 无序        q[c++]=loc;   //入度为零的点入队        temp[loc]=-1;        for(j=1;j<=n;j++)            if(map[loc][j]==1) temp[j]--;    }    return flag;}int main(){    int m,n,i,sign;  //当sign=1时,已得出结果    char str[5];    while(scanf("%d%d",&n,&m))    {        if(m==0&&n==0) break;        memset(map,0,sizeof(map));        memset(indegree,0,sizeof(indegree));        sign=0;        for(i=1;i<=m;i++)        {            scanf("%s",str);            if(sign) continue; //一旦得出结果,对后续的输入不做处理            int x=str[0]-'A'+1;            int y=str[2]-'A'+1;            map[x][y]=1;            indegree[y]++;            int s=TopoSort(n);            if(s==0) //有环            {                printf("Inconsistency found after %d relations.\n",i);                sign=1;            }            if(s==1) //有序            {                printf("Sorted sequence determined after %d relations: ",i);                for(int j=0;j<n;j++)                    printf("%c",q[j]+'A'-1);                printf(".\n");                sign=1;            }        }        if(!sign) //不确定            printf("Sorted sequence cannot be determined.\n");    }    return 0;}


0 0