天天看點

nyoj349 Sorting It All Out(拓撲排序)

  • 題目349
  • ​​題目資訊​​
  • ​​運作結果​​
  • ​​本題排行​​
  • ​​讨論區​​

Sorting It All Out

3000 ms  |  記憶體限制:

65535

3

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 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.

輸出

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. 

樣例輸入

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

樣例輸出

Sorted sequence determined after 4 relations: ABCD.

Inconsistency found after 2 relations.

Sorted sequence cannot be determined.

來源

​​POJ​​

上傳者

​​陳玉​​

剛開始沒有了解題意 。。想了好兩三天 哈哈(好吧 是我懶了)

拓撲排序過程:

1先建圖,然後尋找入讀為0的頂點

2:然後找到與這個頂點有關的邊和點,删去邊,點的入度-1

3.繼續尋找下一個入度為0的頂點。。重複2.

總共三種情況 沖突 可以排序 資訊不完整

判斷沖突 起初我想錯了 總想着并查集判斷成環沖突 可以卻發現我錯的大大的 因為并查集判斷的是集合  也就是無向的

而這道題是有向的。

比如A<B A<C B<C用并查集判斷是一個集合 是不行的。是以還是用我們的強大的深搜判斷有向環

其中判斷沖突 實在輸入的時候就判斷的 可以排序和資訊不完整在輸入資料完畢後再檢查。

拓撲排序處理資訊不完整和沖突

1.如果出現兩個同時入度為0的,并且根是自己就是資訊不完整。

2.如果棧的大小剛好等于比較的數的個數 那麼就是能夠排序 如果棧的大小小于比較的數的個數 就是資訊不完整

用的vector容器模拟鄰接表。queue實作拓撲排序,stack存貯大小

#include <stdio.h>
#include <vector>
#include <string.h>
#include <queue>
#include <stack>
using namespace std;
vector<int>map[27];//鄰接表 
int degree_in[27];//頂點的入度 
bool have[27],vis[27];//hava判斷是否是比較的數 ,vis是在判斷成環的時候 判斷是否已經周遊 
stack<int>s; 
//拓撲排序 
int top_sort(int n)
{
  queue<int>temp;
  int pos;
  while(!s.empty())
  s.pop();
  while(!temp.empty())
  temp.pop(); 
  for(int i=0;i<26;i++)
  {
    if(degree_in[i]==0&&have[i])
    {
      temp.push(i);
      have[i]=false;
    }
  }
  while(!temp.empty())
  {
    if(temp.size()>1)
    return 1;
    pos=temp.front();
    temp.pop();
    s.push(pos);
    for(int i=0;i<map[pos].size();i++)
    {
      if(--degree_in[map[pos][i]]==0)
      temp.push(map[pos][i]); 
    }
  }
  if(s.size()==n)
  return 2;
  else 
  return 1;
}
//判斷是否成有向環 
bool judge(int x)
{
  for(int i=0;i<map[x].size();i++)
  {
    if(vis[map[x][i]])
    return false;
    vis[map[x][i]]=true;
    if(judge(map[x][i]))
    vis[map[x][i]]=false;
    else
    return false;
  }
  return true;
}
int main()
{
  int n,m;
  while(~scanf("%d %d",&n,&m))
  {
    if(!m&&!n)
    break;
    memset(degree_in,0,sizeof(degree_in));
    memset(have,false,sizeof(have));
    memset(map,0,sizeof(map));
    int mark=-1;
    for(int i=0;i<m;i++)
    {
      char ch1,ch2;
      getchar();
      scanf("%c<%c",&ch1,&ch2);
      int a=ch1-'A';
      int b=ch2-'A';
      map[b].push_back(a);
      degree_in[a]++;
      have[a]=have[b]=true;  
      if(mark==-1)
      {
        memset(vis,false,sizeof(vis));
        vis[b]=true;
        if(!judge(b))
        {
          mark=i;
        }     
      }
    }
    if(mark!=-1)
    {
      printf("Inconsistency found after %d relations.\n",mark+1);
      continue;
    }
    else
    {
      int x;
      x=top_sort(n);
      if(x==1)
      printf("Sorted sequence cannot be determined.\n");
      if(x==2)
      {
        printf("Sorted sequence determined after %d relations: ",n);
        while(!s.empty())
        {
          printf("%c",s.top()+'A');
          s.pop();
        }
        printf(".\n");
      }
    }
  }
  return 0;
}