POJ 1094 Sorting It All Out
[★★☆☆☆]拓扑排序
题目大意:
该题题意明确,就是给定一组字母的大小关系判断他们是否能组成唯一的拓扑序列。是典型的拓扑排序,但输出格式上确有三种形式:
1.该字母序列有序,并依次输出;
2.该序列不能判断是否有序;
3.该序列字母次序之间有矛盾,即有环存在。
而这三种形式的判断是有顺序的:先判断是否有环(3),再判断是否有序(1),最后才能判断是否能得出结果(2)。注意:对于(2)必须遍历完整个图,而(1)和(3)一旦得出结果,对后面的输入就不用做处理了。
代码
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int n, m;
int gx[30][30];
int tgx[30][30];
bool u[30];
int que[30];
int ctq;
void cpg() {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
tgx[i][j] = gx[i][j];
}
}
}
int rd(int l){
int res = 0;
for (int i = 1; i <= n; i++) {
res += tgx[i][l];
}
return res;
}
int cd(int l){
int res = 0;
for (int i = 1; i <= n; i++) {
res += tgx[l][i];
}
return res;
}
int yh() {
cpg();
ctq = 0;
int v = -1;
for (int i = 1; i <= n; i++) {
u[i] = 0;
}
while (1) {
v = -1;
bool up = 0;
for (int i = 1; i <= n; i++) {
if (u[i] == 0 && rd(i) == 0) {
v = i; up = 1;
break;
}
}
if (up == 0) break;
que[ctq++] = v;
u[v] = 1;
for (int i = 1; i <= n; i++) {
tgx[v][i] = 0;
}
}
if (ctq == n) return 0;
else return 1;
}
int TOP() {
if (yh()) return -1;
cpg();
ctq = 0;
int v = -1;
for (int i = 1; i <= n; i++) {
u[i] = 0;
}
while (1) {
v = -1;
bool up = 0;
for (int i = 1; i <= n; i++) {
if (u[i] == 0 && rd(i) == 0) {
if (v == -1) {
v = i; up = 1;
}
else return 0; //没有固定顺序
}
}
if (up == 0) break;
que[ctq++] = v;
u[v] = 1;
for (int i = 1; i <= n; i++) {
tgx[v][i] = 0;
}
}
if (ctq == n) return 1;
else return -1;
}
void solve() {
string ts;
for (int js = 0; js < m; js++) {
cin >> ts;
int t1, t2;
t1 = ts[0] - 'A' + 1;
t2 = ts[2] - 'A' + 1;
gx[t1][t2] = 1;
int r = TOP();
if (r == 0) continue;
if (r == -1) {
cout << "Inconsistency found after " << js+1 << " relations." << endl;
for (js++; js<m; js++) cin >> ts;
return;
}
if (r == 1) {
cout << "Sorted sequence determined after " << js+1 << " relations: ";
for (int i = 0; i < ctq; i++) {
char tc = que[i];
tc = tc + 'A' - 1;
cout << tc;
}
cout << '.' << endl;
for (js++; js<m; js++) cin >> ts;
return;
}
}
int r = TOP();
cout << "Sorted sequence cannot be determined." << endl;
return;
}
int main() {
while ((cin >> n >> m) && n) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
gx[i][j] = 0;
}
u[i] = 0;
}
ctq = 0;
solve();
}
return 0;
}
// A B C D E F G