Sorting It All Out
题目链接:http://poj.org/problem?id=1094
题目大意:
输入N,M。N代表有几个字母(从A开始为第一个),M代表有几个关系。关系形如:A<B。
现在问你能否进行拓扑排序,如果可以,拓扑排序是否唯一。
样例:
输入:
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.
解题思路:
这道题目略坑啊。题目的意思是输入一个关系要进行一次判断,如果可以拓扑排序,且答案唯一,就判为可以排序。如果无法排序,就判为矛盾。且不再处理之后的输入。
至于判断拓扑排序是否唯一,只需看相邻的两个字母是否有前后关系即可。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#include <string>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 30;
int n, m, g[maxn][maxn], du[maxn];
char L[maxn];
vector<int> v[maxn];
bool toposort() {
int tot = 0;
queue<int> q;
for (int i = 0; i < n; i++)
for (int j = 0; j < v[i].size(); j++) du[v[i][j]]++;
for (int i = 0; i < n; i++) if (!du[i]) q.push(i);
while(!q.empty()) {
int x = q.front(); q.pop();
L[tot++] = x + 'A';
for (int i = 0; i < v[x].size(); i++) {
int u = v[x][i];
du[u]--;
if (!du[u]) q.push(u);
}
}
if (tot == n) return 1;
return 0;
}
int main () {
char A, O, B;
while(scanf("%d%d", &n, &m)) {
if (!n && !m) break;
mem(g, 0);
mem(L, 0);
int incon = 0, ok = 0;
for (int i = 0; i < n; i++) {
v[i].clear();
du[i] = 0;
}
for (int i = 1; i <= m; i++) {
getchar();
scanf("%c<%c", &A, &B);
if (ok || incon) continue;
int x = A - 'A', y = B - 'A';
if (g[y][x]) incon = i;
else {
g[x][y] = 1;
v[x].push_back(y);
if (toposort()) {
int j;
for (j = 0; j < n - 1; j++) if (g[L[j] - 'A'][L[j + 1] - 'A'] == 0) break;
if (j == n - 1) ok = i;
}
else incon = i;
}
}
if (ok) printf("Sorted sequence determined after %d relations: %s.\n", ok, L);
else if (incon) printf("Inconsistency found after %d relations.\n", incon);
else printf("Sorted sequence cannot be determined.\n");
}
return 0;
}