POJ 1094 拓扑排序

An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from smallest to largest. For example, the sorted sequence A, B, C, D implies that A < B, B < C and C < D. in this problem, we will give you a set of relations of the form A < B and ask you to determine whether a sorted order has been specified or not.

Input

Input consists of multiple problem instances. Each instance starts with a line containing two positive integers n and m. the first value indicated the number of objects to sort, where 2 <= n <= 26. The objects to be sorted will be the first n characters of the uppercase alphabet. The second value m indicates the number of relations of the form A < B which will be given in this problem instance. Next will be m lines, each containing one such relation consisting of three characters: an uppercase letter, the character "<" and a second uppercase letter. No letter will be outside the range of the first n letters of the alphabet. Values of n = m = 0 indicate end of input.

Output

For each problem instance, output consists of one line. This line should be one of the following three: 

Sorted sequence determined after xxx relations: yyy...y. 
Sorted sequence cannot be determined. 
Inconsistency found after xxx relations. 

where xxx is the number of relations processed at the time either a sorted sequence is determined or an inconsistency is found, whichever comes first, and yyy...y is the sorted, ascending sequence. 

Sample Input

4 6
A

Sample Output

Sorted sequence determined after 4 relations: ABCD.
Inconsistency found after 2 relations.
Sorted sequence cannot be determined

 

这道题目考察了拓扑排序的基本思想:每一步寻找一个入度为0的结点,然后删除之。将这个结点指向的结点入度减1。删除从这个结点出发的所有边
同时考察了对于一个有向图是否有环、是否严格有序的判断。(当发现多个结点的度为0时,则不是严格有序。当发现没有结点入度为0时,则有环)
需要注意的是逻辑上的关系。“Sorted sequence cannot be determined.”这个判断,要放在最后,即只有发现了所有的点都没有环,且并没有发现严格有序性质的时候,才可以判为“Sorted sequence cannot be determined."
逻辑上的判决一定要注意优先级。
这个问题中优先级最高的是判断有环。一旦发现找不到度为0的结点,则立即return。
第二优先级是是否严格有序的判断。当每一步能且只能找到一个度为0的结点,则return。
第三优先级是无法确定。(当发现无法确定时,并不能立即return,因为还需要判断是否有环)
思维方式:问问自己,当条件x成立时,另外的条件y,z是否一定不成立。如果一定不成立,则可以断言return。否则必须继续判断下去。

注意:输入一组数据,判断一组数据,若有环或已严格排序则可直接输出结果,后续读入的不做处理,不影响前面的输出结果。但是若前面两个均不成立,切记不严格排序是最后得出的。

附上代码:

#include 
#include 
#include 
#include
using namespace std;
int indegree[27];     //入度
int map[27][27];     //图
int queue[27];       // 每次找到入度为0的点后,存储要输出的顺序
int TopoSort(int n)     //拓扑排序
{
    int count=0;     //记录解空间中零入度顶点的个数
    int temp[27];     //对入度顶点备份
    int pos;      //记录一个零入度顶点的数目
    int i,j;
    int m;       //零入度顶点的个数
    int flag=1;      //flag=1:有序  flag=-1:不能确定
    for (i=1; i<=n; i++)
    {
        temp[i] = indegree[i];  //备份
    }
    for (i=1; i<=n; i++)  //遍历n遍,必须把图全部遍历完(根据当前输入的,尽管map全部初始化为0了,只要根据当前输入的所有条件判断)
    {
        m = 0;
        for (j=1; j<=n; j++)  //查找零入度顶点的个数
        {
            if (temp[j] == 0)
            {
                m ++;
                pos = j;   //记录一个零入度顶点的位置
            }
        }
        if (m == 0)     //零入度顶点的个数==0:有环
        {
            return 0;
        }
  if (m > 1)     //零入度顶点的个数>1,说明还有其他两点之间没确定关系,判断是无序(只有1到n个点确定关系,且没有环,根据拓扑排序才能确定有序)
  {
            flag=-1;    //当知道无序时,并不一定知道该图是否有环,因此要继续遍历,可别急着退出...
        }
        queue[count++] = pos;   //零入度顶点入队
        temp[pos] = -1;    //将零入度顶点的入度置为-1
        for (j=1; j<=n; j++)  //删除以pos为起点的边
        {
            if (map[pos][j] == 1)
            {
                temp[j] --;   //相应定点的入度减1
            }
        }
    }
    return flag;
}
int main()
{
    int n,m;
    int sign;      //当sign=1时,程序已经得出结果,不需再考虑后面的输入
    string str;
    while (scanf("%d%d",&n,&m) && n!=0 && m!=0)
    {
        memset(map,0,sizeof(map));
        memset(indegree,0,sizeof(indegree));
        sign=0;
        for (int i=1; i<=m; i++)
        {
            cin>>str;
            if (sign)
            {
                continue;   //一旦得出结果,对后续的输入置之不理!
            }
            int u = str[0]-'A'+1;
            int v = str[2]-'A'+1;
            map[u][v] = 1;
            indegree[v] ++;
            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

 

你可能感兴趣的:(图论)