- 題目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;
}