拓扑排序 附POJ 1094 Sorting It All Out 解题报告

       拓扑排序是针对有向无环图的概念,通常是用于将一些点进行拓扑排序之后形成一个序列能够形成先后的关系,所以拓扑排序可以用于解决点之间又先后关系的序列。

        POJ1094这道题是说给你一些大小关系,问你是否可以确定这n个字符确定的先后顺序,于是对每一次加入边后,进行拓扑排序,看是否形成了一个有向无环图,并且此时的序列是唯一的。因为题目要求中大小是一个确定序列,所以只有当拓扑排序之后的序列是确定的,那么就是确定了这个序列了的。

        题目中需要判断是否存在环,于是我们只需要在进行拓扑排序完成之后看看序列中的点的个数是否是n个,否则就是存在环。还有就是当我们是唯一确定一个序列的时候,那么这个时候 进行拓扑排序的过程中,队列中的点的个数必然是1,否则就是不确定的拓扑排序,这里需要小心判断,不然wa到死。

         注意好了这些就可以安安全全的ac了。下面贴上我的AC代码:

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
const int Max=26;
int indegree[Max];
vector<int> adj[Max];

int getVal(char ch)
{
    return ch-'A';
}

void init(int n)
{
    for(int i=0;i<n;i++)
    {
        adj[i].clear();
    }
    memset(indegree,0,sizeof(indegree));
}

int path[Max+2],plen;

int checkWrong(int n)
{
    int inde[Max];
    for(int i=0;i<n;i++)
        inde[i]=indegree[i];
    int flag=0;
    queue<int> q;
    for(int i=0;i<n;i++)
    {
        if(inde[i]==0)
        {
            q.push(i);
            flag++;
        }
    }
    plen=0;
    while(!q.empty())
    {
        int fr=q.front();
        if(q.size()>1)
            flag=2;
        q.pop();
        path[plen++]=fr;
        int len=adj[fr].size();
        for(int i=0;i<len;i++)
        {
            int next=adj[fr][i];
            inde[next]--;
            if(inde[next]==0)
            {
                q.push(next);
            }
        }
    }
    if(plen<n)
        return 1;
    if(plen==n&&flag==1)
        return 2;
    return 0;
}

int check(int st,int en)
{
    int len=adj[st].size();
    for(int i=0;i<len;i++)
    {
        if(adj[st][i]==en)
            return 1;//是重边
    }
    return 0;
}
int main()
{
    int n,m;
    int flag,ans,i;
    char s[20];
    while(scanf("%d %d",&n,&m))
    {

        if(n==0&&m==0)
            break;
        init(n);
        flag=0;
        for(i=1;i<=m;i++)
        {
            //cin>>s;
            scanf("%s",s);
           // cout<<s<<endl;
            int st=getVal(s[0]);
            int en=getVal(s[2]);
            if(check(st,en)==0)
            {
                adj[st].push_back(en);
                indegree[en]++;
            }
         //   printf("before check\n");
            int temp=checkWrong(n);
         //   printf("after checkWrong\n");
            if(temp==1)
            {
                flag=1;
                ans=i;
                break;
            }
            else if(temp==2)
            {
                flag=2;
                ans=i;
                break;
            }
        }
        for(i=i+1;i<=m;i++)
        {
            scanf("%s",s);
        }
        if(flag==0)
        {
            printf("Sorted sequence cannot be determined.\n");
        }
        else if(flag==1)
        {
            printf("Inconsistency found after %d relations.\n",ans);
        }
        else if(flag==2)
        {
            printf("Sorted sequence determined after %d relations: ",ans);
            for(i=0;i<plen;i++)
            {
                printf("%c",'A'+path[i]);
            }
            printf(".\n");
        }
    }
    return 0;
}


你可能感兴趣的:(拓扑排序 附POJ 1094 Sorting It All Out 解题报告)