POJ1094 Sorting It All Out 拓扑排序

题目大意:给你n个大写字母(从A开始往后数n-1个)和m组字母之间的关系(X<Y表示X在Y的前面),让你判断这些字母之间先后关系:

(1)k组关系后(k<=m)若能判断出n个字母之间的先后关系,那么输出这个序列;

(2)k组关系后(k<=m)若判断出有相互矛盾的关系存在,那么输出错误;

(3)m组关系后若仍不能判断n个字母之间的关系,那么就输出否。



分析:很明显的拓扑排序,但我们要先明确这3个输出的优先级:(2)的优先级最高,其次是(1),(3)的优先级最低。原因很简单,首先(1)(2)不一定需要遍历这m组关系,而且我们在找出正确关系的过程中若发现矛盾(即判断出了(2)),那么就不再执行(1)了。

    拓扑排序的模板很多,下面我分别用了可达矩阵和STL容器类两种方法:


可达矩阵实现代码如下:

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int edge[30][30],ind[30];
int seq[30];
int Top_sort(int n)
{
    int d[30],dnum,d0;//d[]用来存放当前情况下的顶点入度,dnum表示入度为0的个数,d0表示入度为0的顶点的编号
    int cnt=0;
    int flag=1;
    for(int i=0;i<n;i++)
      d[i]=ind[i];
    for(int i=0;i<n;i++)
    {
        dnum=0;
        for(int j=0;j<n;j++)
          if(d[j]==0)
          {
              dnum++;
              d0=j;
          }
        if(dnum==0) return -1;
        if(dnum>1) flag=0;
        seq[cnt++]=d0;
        d[d0]=-1;
        for(int j=0;j<n;j++)
          if(edge[d0][j]) d[j]--;

    }
    return flag;
}
int main()
{
    int m,n;
    while(scanf("%d%d",&n,&m))
    {
        if(m==0&&n==0) break;
        char u,c,v;
        bool flag=false;
        memset(edge,0,sizeof(edge));
        memset(ind,0,sizeof(ind));
        for(int i=1;i<=m;i++)
        {
            cin>>u>>c>>v;
            if(flag) continue;
            u-='A';
            v-='A';
            edge[u][v]=1;
            ind[v]++;
            int cnt=Top_sort(n);
            if(cnt==1)
            {
                printf("Sorted sequence determined after %d relations: ",i);
                for(int j=0;j<n;j++)
                    printf("%c",seq[j]+'A');
                printf(".\n");
                flag=true;
            }
            if(cnt==-1)
            {
                printf("Inconsistency found after %d relations.\n",i);
                flag=true;
            }
        }
        if(!flag) puts("Sorted sequence cannot be determined.");
    }
    return 0;
}


用STL中vector容器类和queue的实现代码如下:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
vector <int> edge[30];
int indgree[30],seq[30];
int Top_sort(int n)
{
    queue<int> que;
    int ind[30];
    int tmp=0;
    bool res=false;
    for(int i=0;i<n;i++)
    {
        ind[i]=indgree[i];
        if(ind[i]==0) que.push(i);
    }
    while(!que.empty())
    {
        if(que.size()>1) res=true;
        int cnt=que.front();
        que.pop();
        seq[tmp++]=cnt;
        for(int i=0;i<edge[cnt].size();i++)
        {
            ind[edge[cnt][i]]--;
            if(ind[edge[cnt][i]]==0) que.push(edge[cnt][i]);
        }
    }
    if(tmp<n) return -1;
    if(res) return 0;
    return 1;
}
int main()
{
    int n,m,i;
    char u,c,v;
    while(scanf("%d%d",&n,&m))
    {
        if(n==0&&m==0) break;
        memset(indgree,0,sizeof(indgree));
        int flag;
        bool judge=0;
        for(i=0;i<=30;i++)
          edge[i].clear();
        for(i=1;i<=m;i++)
        {
            cin>>u>>c>>v;
            if(judge) continue;
            u-='A';
            v-='A';
            edge[u].push_back(v);
            indgree[v]++;
            flag=Top_sort(n);
            if(flag==-1)
            {
                printf("Inconsistency found after %d relations.\n",i);
                judge=1;
            }
            else if(flag==1)
            {
                printf("Sorted sequence determined after %d relations: ",i);
                for(int k=0;k<n;k++)
                  printf("%c",seq[k]+'A');
                printf(".\n");
                judge=1;
            }
        }
        if(!judge) puts("Sorted sequence cannot be determined.");
    }
    return 0;
}


你可能感兴趣的:(POJ1094 Sorting It All Out 拓扑排序)