看discuss好多人用拓扑排序做的,思想很有启发性,可以尝试下。下面是我的解法:
/*
* poj 1094 全排序问题
题目大意:
题目给出一组两两元素间的严格弱序关系,逐对的读入各关系对,判断到目前对儿为止
能否给出所有元素的全排序关系,或者发现了前后矛盾的关系,甚至读完所有的对儿仍无
法确定全排序关系。
数学模型:
m[i, j]表示元素i与元素j相比较的大小结果: -1表示小雨,0表示相等,1表示大于
解题思路:
1、读入关系对a<b
2、遍历m[a]行,寻找所有元素x<=a -- 其实只有a=a。
3、遍历m[b]行,寻找所有元素y>=b。
4、针对每对(a,b)更新m[a,b]和m[b,a]。更新的同时检查m[a,b]的值:
4.1、如果m[a,b]==1表示发现矛盾对,结束本测试例的处理,输出矛盾。
4.2、如果没发现矛盾,则检查是否所有m的元素都有了合法值?
如果是表示全序关系已经可以确定,结束查找,根据该m表各值排序各元素即可。
如果不是返回第3步,继续。
注意事项:
1、本题第4.2步中,即使检测到所有m的元素均有非法值了,仍然要执行完该关系对的处理。
因为该关系对引发的直接或者连锁关系中可能会有矛盾存在。见文件底部测试例9
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
namespace {
using namespace std;
const int N_MAX = 26;
int matrix[N_MAX][N_MAX]; // 关系记录矩阵
char sequence[N_MAX]; // 待排序元素记录
// 元素比较函数
int object_cmp(const void *pOP1, const void *pOP2)
{
char *pCh1 = (char *)pOP1;
char *pCh2 = (char *)pOP2;
return matrix[*pCh1-'A'][*pCh2-'A'];
}
}
int main()
{
int n, m;
while (scanf("%d %d", &n, &m))
{
if (n==0 || m==0)
{
break;
}
// 状态初始化
for (int i=0; i<n; i++)
{
sequence[i] = 'A'+i;
}
memset(matrix, 0, sizeof(matrix));
// 算法核心部分
int nLeft = n*n - n; // matrix中待决定的关系对数
int nCurRelation = 0; // 当前处理的关系对序数,当能决定个元素的全序后,该计数停止增长
bool bInconsistency = false; // 矛盾标志
char relation[8]; // 关系字符串存储
int xi, yi; // a和b的编号
for (int k=0; k<m; k++)
{
scanf("%s", relation); // 持续读入,即使已经有答案了也要执行,否则影响下一测试例
xi = relation[0] - 'A';
yi = relation[2] - 'A';
if (!bInconsistency && nLeft>0)
{
nCurRelation++;
}
for (int j1=0; j1<n && !bInconsistency && nLeft>=0; j1++)
{
if (matrix[xi][j1]!=1 && j1!=xi) continue; // 查找x<=a
for (int j2=0; j2<n && !bInconsistency && nLeft>=0; j2++)
{
if (matrix[yi][j2]!=-1 && j2!=yi) continue; // 查找y>=b
if (matrix[j1][j2] == 1) // 检查矛盾
{
bInconsistency = true;
continue;
}
if (matrix[j1][j2] == -1) continue; // 如果该关系已被处理过,不再处理
matrix[j1][j2] = -1; // 置m[x][y]和m[y][x]
matrix[j2][j1] = 1;
nLeft -= 2; // 待定关系对减2
}
}
}
if (bInconsistency) // 优先检查矛盾与否
{
printf("Inconsistency found after %d relations.\n", nCurRelation);
}
else if (nLeft>0) // 检查是否可以决定全序
{
printf("Sorted sequence cannot be determined.\n");
}
else
{
sequence[n] = '\0';
qsort(sequence, n, sizeof(char), object_cmp); // 排序
printf("Sorted sequence determined after %d relations: %s.\n", nCurRelation, sequence);
}
}
return 0;
}
/*
poj 测试数据9
10 40
E<J
C<A
G<J
C<H
G<I
A<I
D<I
D<A
G<E
F<I
A<J
D<H
E<B
A<B
D<E
E<I
D<C
C<G
F<A
F<H
D<B
I<J
I<B
F<C
J<B
D<F
G<H
A<H
I<H
A<E
E<H
F<J
H<B
G<A
G<F
D<G
F<E
F<B
C<B
C<I
0 0
我就是这组数据错了,导致第一次提交WA,本数据的正确结果应该是:
Inconsistency found after 35 relations.
但是我一开始的结果却是:
Sorted sequence determined after 35 relations: DFCGAEIHJB.
该结果显然与第35组关系对G<F矛盾。之所以产生这样的矛盾,就在于
原程序在处理该关系时,优先处理该关系引起的传递关系,导致nLeft
减为0,之后不再处理引起的其他反应--包括该关系对本身。
修改很简单,把原来判断nLeft>0的地方改成nLeft>=0即可。
*/