Sorting It All Out
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 22173 | Accepted: 7647 |
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.
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.
Source
解题思路:拓扑排序的题,首先明确存在以下几种情况:
1.根据已知条件构成的图中存在环,就是说存在逻辑矛盾,这个用Warshall算法判定关系序偶集合中有无传递闭包,有就是存在环。
2.根据已知条件构不成完全图,就是字母数不足,这样就没办法组成拓扑序列。
3.根据已知条件构成的图中有不只一的点的入度为0,这样组成的拓扑序列就不唯一。
4.根据已知条件构成的图,可以组成唯一的拓扑序列。
以上2,3,4条的关键判定条件为是否图中所有点的出入度之和均为顶点数减1,若是的话,则证明有唯一的拓扑序列存在。
#include<iostream>
#include<queue>
using namespace std;
int map[30][30],indegree[30],outdegree[30],num[30],m,n;
bool deleted[30];
char topo[30];
bool Warshall()
//计算关系集合中有无传递闭包,有的话就说明关系间存在矛盾
{
int i,j,k;
for(k=0;k<n;k++)
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(map[i][k]&&map[k][j])
map[i][j]=1;
for(i=0;i<n;i++)
if(map[i][i])
return true;
return false;
}
bool Calculate()
{
int i,j;
memset(indegree,0,sizeof(indegree));
memset(outdegree,0,sizeof(outdegree));
for(i=0;i<n;i++)
for(j=0;j<n;j++)
//计算图中顶点的度数
if(map[i][j])
{
indegree[j]++;
outdegree[i]++;
}
for(i=0;i<n;i++)
if(indegree[i]+outdegree[i]!=n-1)//判断根据已有关系是否能构成一幅完整的图且该图中入度为0的点只有一个
return false;
return true;
}
void Topo_sort()
{
int i,j=0,k=0;
queue <int> q;
memset(deleted,false,sizeof(deleted));
for(i=0;i<n&&k<=1;i++)
if(!indegree[i])//将没有入度的点作为拓扑序列的第一个入队,同时保证这样的点只有一个
{
q.push(i);
k++;
}
while(!q.empty())
{
int t=q.front();
q.pop();
deleted[t]=true;//将队列中的点写入拓扑序列,同时将这一点从图中删除
topo[j++]=t+'A';
for(i=0;i<n;i++)
if(!deleted[i])
//对于图中剩下的点
{
if(map[t][i])//若有入度是刚才删去点所发出,删去这一条边
indegree[i]--;
if(indegree[i]==0)//若删去后使得该点入度为0,将此点加入拓扑序列
q.push(i);
}
}
topo[j]='\0';
}
int main()
{
int i,flag1,flag2;
char relation[3];
while(cin>>n>>m&&(m||n))
{
memset(map,0,sizeof(map));
flag1=flag2=0;
for(i=1;i<=m;i++)
{
cin>>relation;
map[relation[0]-'A'][relation[2]-'A']=1;//根据题目所给关系构图,用来表示前者到后者的一条有向边
if(flag1||flag2) continue;//根据已输入关系可以判断可否构成拓扑序列,后续输入就无意义了
if(Warshall())
//不能构成拓扑序列且关系间存在矛盾
{
flag1=i;
continue;
}
else if(Calculate())
//能构成拓扑序列且只有唯一一个拓扑序列
{
Topo_sort();
flag2=i;
}
}
if(flag1)
cout<<"Inconsistency found after "<<flag1<<" relations.\n";
else if(flag2)
cout<<"Sorted sequence determined after "<<flag2<<" relations: "<<topo<<".\n";
else
cout<<"Sorted sequence cannot be determined.\n";//拓扑序列不唯一
}
return 0;
}