一道题搞了一晚上。。还好最后搞出来了,哈哈,小有成就感,这题细节上没参考别人的思路和代码,难点在于,如果有矛盾的偏序关系或者目前的条件能够推出顺序关系,需要实时地判断出来,后面给出的关系就被丢弃不考虑了。本题我的思路是实时用floyd求传递闭包,如果给出条件形成了环,则必有矛盾关系,这个还简单,如果当前的所有条件能够成顺序关系,我的判断依据是:假设有四个点ABCD构成A<B<C<D,那A必有3个可达点,B必有2个可达点,C必有1个可达点,D没有可达点,每个不多也不少,多了就有环,少了就构不成顺序关系,这个还是洗澡时冒出的灵感。。判断有顺序关系之后,就用DFS求图的拓扑排序,然后根据完成的时间给出顺序关系,这个参考了算法导论的代码。最后上代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<limits.h>
struct Point
{
char c;
int time;
};
static int n, m, map[26][26], adj[26][26], visit[26], path[26], time;
static struct Point *array;
static void dfs(int p)
{
visit[p] = 1;
time++;
int i;
for (i = 0; i < n; i++)
if (adj[p][i] && !visit[i])
dfs(i);
array[p].time = ++time;
}
static int cmp(const void *p1, const void *p2)
{
struct Point *t1 = (struct Point *) p1;
struct Point *t2 = (struct Point *) p2;
return t2->time - t1->time;
}
static int cmp_int(const void *p1, const void *p2)
{
int *i1 = (int *) p1;
int *i2 = (int *) p2;
return *i1 - *i2;
}
static int floyd(int a, int b)
{
int temp[2] =
{ a, b };
int i, j, ki, k;
memset(path, 0, sizeof(path));
for (ki = 0; ki < 2; ki++)
{
k = temp[ki];
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
map[i][j] = map[i][j] || (map[i][k] && map[k][j]);
if (ki && map[i][j])
path[i]++;
}
}
}
qsort(path, n, sizeof(int), cmp_int);
for (i = 0; i < n; i++)
if (path[i] != i)
return 0;
return 1;
}
int main()
{
char s[4];
array = malloc(26 * sizeof(struct Point));
while (scanf("%d %d", &n, &m), n || m)
{
getchar();
memset(map, 0, sizeof(map));
memset(adj, 0, sizeof(map));
int a, b, i, mi, consist = 1, find = 0;
for (mi = 1; mi <= m; mi++)
{
gets(s);
a = s[0] - 'A';
b = s[2] - 'A';
adj[a][b] = 1;
if (!consist || find)
continue;
if (map[b][a] || a == b)
{
consist = 0;
printf("Inconsistency found after %d relations.\n", mi);
}
if (consist && !find)
{
map[a][b] = 1;
if (floyd(a, b))
{
find = 1;
time = 0;
memset(visit, 0, sizeof(visit));
for (i = 0; i < n; i++)
array[i].c = 'A' + i;
for (i = 0; i < n; i++)
if (!visit[i])
dfs(i);
qsort(array, n, sizeof(struct Point), cmp);
printf("Sorted sequence determined after %d relations: ",
mi);
for (i = 0; i < n; i++)
putchar(array[i].c);
puts(".");
}
}
}
if (consist && !find)
puts("Sorted sequence cannot be determined.");
}
free(array);
return 0;
}