POJ 1094 Sorting It All Out(拓撲排序 入度性質)

原題

Sorting It All Out

Time Limit: 1000MS Memory Limit: 10000K


Description


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<B
A<C
B<C
C<D
B<D
A<B
3 2
A<B
B<A
26 1
A<Z
0 0

Sample Output


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

題意

依次給定一組字母的大小關係,並及時判斷它們是否能組成唯一的拓撲序列。

涉及知識及算法


題解的強大之處在於靈活利用了入度這個概念,存在解的時候,必須滿足只有一個單源點,沿着解這條路走,必然是單源點(入度爲零)後面跟着入度爲1的點, 然後刪除單源點,更新入度,重複,又是僅有一個單源點,且後面跟着入度爲1的點,最後僅剩一個單源點。有環的話,隨着單源點的刪除,最後會出現沒有單源點的情況,這個時候就可以判讀處理有環。 無序的話,無論什麼時候,出現多個單源點都說明無序。
——引自CSDN博主chchlh,附上鍊接http://blog.csdn.net/chchlh/article/details/41846509,表示感謝。

代碼

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int n,m;
//最終判斷的標記
bool Sign;
//錄入字符串
string str;
//入度數組
int indegree[27];
//圖
int Map[27][27];
//解空間(隊列)
int q[27];
//備份入度頂點
int temp[27];
//拓撲排序
int TopoSort()
{
    //記錄解空間中零入度頂點的個數
    int Count=0;
    //記錄任一個零入度頂點的位置
    int loc;
    //記錄當前圖中零入度頂點數目
    int m;
    //暫標記爲有序
    int flag=1;
    for(int i=1;i<=n;i++)
    {
        temp[i]=indegree[i];
    }
    for(int i=1;i<=n;i++)
    {
        m=0;
        //查找零入度頂點個數
        for(int j=1;j<=n;j++)
        {
            if(temp[j]==0)
            {
                m++;
                //記錄一個零入度頂點位置
                loc=j;
            }
        }
        //當前圖中零入度頂點數目爲零一定說明有環
        if(m==0)
        {
            return 0;
        }
        //無序,但不一定知道是否有環
        if(m>1)
        {
            flag=-1;
        }
        //該零入度頂點入隊
        q[Count++]=loc;
        //入度置爲-1
        temp[loc]=-1;
        //刪除該點
        for(int j=1;j<=n;j++)
        {
            if(Map[loc][j]==1)
            {
                temp[j]--;
            }
        }
    }
    return flag;
}
int main()
{
    //freopen("in.txt","r",stdin);
    while(scanf("%d%d",&n,&m)&&(n||m))
    {
        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();
            //有環
            if(s==0)
            {
                printf("Inconsistency found after %d relations.\n",i);
                Sign=1;
            }
            //有序
            else if(s==1)
            {
                printf("Sorted sequence determined after %d relations: ",i);
                for (int j=0; j<n; j++)
                {
                    putchar(q[j]+'A'-1); //輸出字符 putchar(ASCII)
                }
                printf(".\n");
                Sign=1;
            }
        }
        //無法得出結果
        if(!Sign)
        {
             printf("Sorted sequence cannot be determined.\n");
        }
    }
    return 0;
}
 
/**************************************************************
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1508 kb
****************************************************************/

代碼引自新浪博客博主康文騏,附上鍊接http://blog.sina.com.cn/s/blog_676070110100kii1.html,表示感謝。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章