POJ 1094 Sorting It All Out(经典拓扑,唯一排序)

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.

//很好的一道拓扑排序题目,

#include <iostream>
#include <stack>
#include <string.h>
#include <stdio.h>
#define N 33
using namespace std;
int main()
{   freopen("in.txt","r",stdin);
    int i,j,n,m,t,record;
 short int x,y;
 bool e[N][N],use[N];
 int v[N],tv[N],re[N];
 char h[133],a,c,b;
 bool f,f1,f2;
 for(j=1,i='A';i<='Z';i++)
  h[i]=j++;
 stack<int>St;
    while(scanf("%d%d",&n,&m),n||m)
 {
     while(!St.empty())
      St.pop();
      memset(v,0,sizeof(v));
   memset(e,0,sizeof(e));
   memset(use,0,sizeof(use));
  getchar();t=0;
  f1=f2=1;
      for(i=1;i<=m;i++)
   {
    scanf("%c%c%c",&a,&c,&b);getchar();
      if(f1==0||f2==0)
     continue;

        x=h[a];y=h[b];
       if(!e[x][y])//确认加人的是条新边
    {  
          if(!use[x])//确认该点是否出现过
    {
         t++;
      use[x]=1;
    }
       if(!use[y])//确认该点是否出现过
    {
          t++;
       use[y]=1;
    }
             e[x][y]=1;
    v[y]++;//计算点的入度
          

         for(j=1;j<=n;j++)
   {    tv[j]=v[j];
        if(use[j]&&!tv[j])//如果该点存在,且入度为0,则入栈。
        St.push(j);
   }   f=1;

             if(St.size()>1)//判断拓扑排序起点是否唯一
                 f=0;

    int index=0;
      while(!St.empty())
   {
          int temp=St.top();//拓扑起点
        St.pop();     //删除该点
       re[index++]=temp;
        for(j=1;j<=n;j++)
     {
          if(e[temp][j])
       {
            tv[j]--;  //删除以该点为起始的有向边
        if(!tv[j])
         St.push(j);
       }
   
     }
     if(St.size()>1)//判断拓扑排序起点是否唯一
     f=0;
   }
      for(j=1;j<=n;j++)

         if(tv[j]) //说明存在环了
      {
      f1=0;record=i;
       break;
      }
       if(t==n&&f&&f1)//开始时f1忘记加进来了,有环时就不再往下做了。
    {
         f2=0;record=i;
        continue;
    }
    }
  }
   if(!f2)
  {
      printf("Sorted sequence determined after %d relations: ",record);
     for(i=0;i<n;i++)
      printf("%c",re[i]+64);
     printf(".\n");
  
  }else if(!f1)
  {
     printf("Inconsistency found after %d relations.\n",record);
  }else
  {
   printf("Sorted sequence cannot be determined.\n"); 
  }
 
 }

     return 0;
}

//今天再次看了下Bellman Ford 算法,理解加深了些了!

  时隔几个月、再次写下这题

#include <iostream>

#include <stdio.h>

#include <queue>

#include <stack>

#include <set>

#include <vector>

#include <string.h>

#include <algorithm>

using namespace std;

char rc[29];

int temp[29];

int in[29];

vector<int> ve[29];

int n,cnt;

int topsort()

{

    stack<int> S;

    int i,id=0;

    bool f=1;

    for(i=0;i<n;i++)

     {

         temp[i]=in[i];

         if(in[i]==0)

         S.push(i);

     }

     if(S.size()>1) f=0;

     int d,l;

     while(!S.empty())

     {

         d=S.top();S.pop();

         rc[id++]=(char)d+'A';

         for(l=ve[d].size(),i=0;i<l;i++)

          if(--temp[ve[d][i]]==0)

             S.push(ve[d][i]);

         if(S.size()>1) f=0;

     }

     rc[id]='\0';

     for(i=0;i<n;i++) if(temp[i]) return -1;

     if(f&&id==n) return 1;

     return 0;



}

int main()

{

    int m,i;

    char op[5];

    int a,b;

    int flag,p,k;

    while(scanf("%d %d",&n,&m),n)

    {

        memset(in,0,sizeof(in));

        cnt=p=k=0;

        for(i=0;i<m;i++)

        {

            scanf("%s",op);

            a=op[0]-'A';

            b=op[2]-'A';

            //if(ve[a].size()==0) cnt++;

          //  if(ve[b].size()==0) cnt++;

             ve[a].push_back(b);

             in[b]++;

            if(p==0) flag=topsort();

            if(p==0)

            {

                if(flag==-1)

                {

                    k=i+1;

                    p=-1;

                }

                if(flag==1)

                {

                    k=i+1;

                    p=1;

                }

            }

        }

        if(p==1)

        printf("Sorted sequence determined after %d relations: %s.\n",k,rc);

        else if(p==0)

             printf("Sorted sequence cannot be determined.\n");

             else

             printf("Inconsistency found after %d relations.\n",k);

        for(i=0;i<n;i++) ve[i].clear();

    }

    return 0;

}

你可能感兴趣的:(sort)