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;
}
原文地址:https://www.cnblogs.com/372465774y/p/2461117.html