ZOJ-1060

一道题搞了一晚上。。还好最后搞出来了,哈哈,小有成就感,这题细节上没参考别人的思路和代码,难点在于,如果有矛盾的偏序关系或者目前的条件能够推出顺序关系,需要实时地判断出来,后面给出的关系就被丢弃不考虑了。本题我的思路是实时用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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值