poj 1094 Sorting It All Out(拓扑排序)

http://poj.org/problem?id=1094

拓扑排序,有点坑。

给出m个关系,在输入的同时判断在当前条件下是否有环,是否能形成唯一拓扑序列,或者是不确定。

此题要注意优先级,当在输入的过程中出现环或拓扑排序成功时可以直接输出,但当前驱结点不唯一时不能直接输出,因为后面的输入可能导致出现环,这时候就应该输出矛盾而不是拓扑序列不唯一了,所以判拓扑序列不唯一时应放在输入完毕后


#include<stdio.h>
#include<string.h>
int n,m,cnt;
int degree[30];
bool map[30][30];
char topo[30];

int toposort()
{
    int indegree[30];//函数内部设一个记录入度的数组,尝试着进行拓扑;
    int i,j,k,m;
    for(i = 0; i < n; i++)
        indegree[i] = degree[i];
    cnt = 0;
    m = 0;//判断是否有多个前驱结点,注意初始化放在外循环外面;

    for(i = 0; i < n; i++)
    {
        for(j = 0; j < n; j++)
        {
            if(indegree[j] == 0)
            {
                topo[cnt++]  = j+'A';//进拓扑序列;
                indegree[j]--;
                for(k = j+1; k < n; k++)
                {
                    if(indegree[k] == 0)
                        m = 1;//m=1说明有多个前驱结点,拓扑序列不唯一;
                }
                for(k = 0; k < n; k++)
                {
                    if(map[j][k] == 1)
                        indegree[k]--;//与j相连的结点入度减一;
                }
                break;
            }

        }
    }
    topo[cnt] = '\0';
    if(cnt < n)
        return -1;//若n次循环后前驱结点数小于n说明有环;
    else if(m == 1) return 0;//m=1说明有多个前驱结点,拓扑序列不唯一;
    else return 1;
}
int main()
{
    int i,res;
    char u,v;
    while(~scanf("%d %d",&n,&m))
    {
        if(n == 0 && m == 0)
          break;
        getchar();
        memset(map,0,sizeof(map));
        memset(degree,0,sizeof(degree));

        int ok = 0;
        for(i = 1; i <= m; i++)
        {
            if(ok == 0)
            {
                scanf("%c<%c",&u,&v);
                getchar();
                degree[v-'A']++;
                map[u-'A'][v-'A'] = 1;
                res = toposort();
        
                if(res == -1)
                {
                    //有环时直接输出
                    printf("Inconsistency found after %d relations.\n",i);
                    ok = 1;
                    continue;
                }
                else if(res == 1)
                {   //当只有一个前驱结点时才输出拓扑序列。
                    printf("Sorted sequence determined after %d relations: ",i);
                    printf("%s.\n",topo);
                    ok = 1;
                    continue;
                }
            }
            else
            {
                scanf("%c<%c",&u,&v);
                getchar();
            }
        }
        if(ok == 0)
            printf("Sorted sequence cannot be determined.\n");
    }
    return 0;
}


你可能感兴趣的:(拓扑排序)