题意:给定一组字母的大小关系判断他们是否能组成唯一的拓扑序列。
题解:这是典型的拓扑排序,但输出格式上确有三种形式:
1.该字母序列有序,并依次输出;
2.该序列不能判断是否有序;
3.该序列字母次序之间有矛盾,即有环存在。
而这三种形式的判断是有顺序的:先判断是否有环(3),再判断是否有序(1),最后才能判断是否能得出结果(2)。注意:对于(2)必须遍历完整个图,而(1)和(3)一旦得出结果,对后面的输入就不用做处理了。注意顺序。
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
const int sz = 26 + 5;
int n,m,cnt;
bool mp[sz][sz];
bool vis[sz];
bool ok;
int in[sz],inn[sz];
queue <int> q;
void topsort(int k){
bool fl = 0;
memset(vis, 0, sizeof(vis));
while(!q.empty()) q.pop();
for(int i = 1; i <= n; i++)
inn[i] = in[i];
for(int ii = 1,p; ii <= n; ii++){
cnt = 0;
for(int i = 1; i <= n; i++){
if(inn[i] == 0 && vis[i] == 0){
p = i;
cnt++;
}
}
if(cnt == 0){
printf("Inconsistency found after %d relations.\n", k);
ok = 1;
return;
}
if(cnt > 1)
fl = 1;
q.push(p);
vis[p] = 1;
for(int j = 1; j <= n; j++)
if(mp[p][j]) inn[j]--;
}
if(fl == 1) return;
printf("Sorted sequence determined after %d relations: ", k);
while(!q.empty()){
printf("%c", q.front() + 'A' - 1);
q.pop();
}
puts(".");
ok = 1;
}
int main(){
while(scanf("%d%d", &n, &m) && n && m){
memset(mp, 0, sizeof(mp));
memset(in, 0, sizeof(in));
ok = 0;
for(int i = 1; i <= m; i++){
char s[10];
scanf("%s", s);
if(ok == 1) continue;
if(!mp[s[0] - 'A' + 1][s[2] - 'A' + 1])
in[s[2] - 'A' + 1]++;
mp[s[0] - 'A' + 1][s[2] - 'A' + 1] = 1;
topsort(i);
}
if(ok == 1) continue;
printf("Sorted sequence cannot be determined.\n");
}
return 0;
}