拓扑排序题目

 

 

1、题目描述

有时候,给出一些事物中的部分相对关系,就可以确定全部事物之间的关系。现在有n(2<= n <= 26)种事物,用大写字母'A'-'Z'来表示,现在给出这些事物中的部分事物之间的大小关系,例如n=4时有事物A,B,C,D.并且给出关系A<B,B<C,C<D.就可以唯一确定A,B,C,D从小到大的序列:ABCD.

解答要求:

时间限制:1000ms,内存限制:64M

输入:

输入的第一行包含两个数字:n和m(1<= m <= 500),表示事物的数目和将要给出的关系数。接下来的m行,每行将给出这n个事物中的某两个事物的大小关系,用'<'连接。

输出:

1、如果这m个关系式中存在矛盾的关系,比如A<B,B<A,则输出 Inconsistency found after i relations. 表示第i个关系式首次出现了矛盾,并且不再判断后面的关系式。

2、如果这m个关系式没有矛盾但是这些关系不能确定这n个事物的大小关系,就输出 Sorted sequence cannot be determined.

3、如该得到i个关系式后就能唯一确定这n个事物的大小关系,就输出 Sorted sequence determined after i relations:XXX...XX. 并且不再判断后面的关系式。

 

样例:

4 6

A<B

A<C

B<C

C<D

B<D

A<B

输出样例1:

Sorted sequence determined after 4 relations:ABCD.

提示:

本题可以用拓扑排序来做。

 

拓扑排序(Topological Sort)

偏序(Partial Order)

全序(Full Order)

偏序指集合中仅有部分成员之间可以比较,而全序指集合中全体成员之间均可以比较。

 

有向图:给定n个顶点和m条弧,就有三种情况:

  1. 能确定这n个顶点的唯一拓扑序列,即这n个顶点可以排列优先顺序,即图中的所以顶点之间均可以比较优先级
  2. 该有向图存在环,不能确定这n个顶点之间的优先顺序
  3. 该有向图无环,但这m个关系式(弧)还不足以唯一确定这n个顶点之间的优先关系。

 

 

// Topo.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"


//https://blog.csdn.net/m0_37357063/article/details/103224795
//1、题目描述
//有时候,给出一些事物中的部分相对关系,就可以确定全部事物之间的关系。
//现在有n(2<= n <= 26)种事物,用大写字母'A'-'Z'来表示,
//现在给出这些事物中的部分事物之间的大小关系,
//例如n=4时有事物A,B,C,D.并且给出关系A<B,B<C,C<D.
//就可以唯一确定A,B,C,D从小到大的序列:ABCD.
//解答要求:
//时间限制:1000ms,内存限制:64M
//输入:
//输入的第一行包含两个数字:n和m(1<= m <= 500),表示事物的数目和将要给出的关系数。
//接下来的m行,每行将给出这n个事物中的某两个事物的大小关系,用'<'连接。
//输出:
//1、如果这m个关系式中存在矛盾的关系,比如A<B,B<A,
//则输出 Inconsistency found after i relations.
//表示第i个关系式首次出现了矛盾,并且不再判断后面的关系式。

//2、如果这m个关系式没有矛盾但是这些关系不能确定这n个事物的大小关系,
//就输出 Sorted sequence cannot be determined.

//3、如该得到i个关系式后就能唯一确定这n个事物的大小关系,
//就输出 Sorted sequence determined after i relations:XXX...XX.
//并且不再判断后面的关系式。

//样例:

//4 6

//A<B

//A<C

//B<C

//C<D

//B<D

//A<B

//输出样例1:
//Sorted sequence determined after 4 relations:ABCD.

//提示:
//本题可以用拓扑排序来做。
//拓扑排序(Topological Sort)
//偏序(Partial Order)
//全序(Full Order)
//偏序指集合中仅有部分成员之间可以比较,而全序指集合中全体成员之间均可以比较。
//有向图:给定n个顶点和m条弧,就有三种情况:
//能确定这n个顶点的唯一拓扑序列,即这n个顶点可以排列优先顺序,即图中的所以顶点之间均可以比较优先级
//该有向图存在环,不能确定这n个顶点之间的优先顺序
//该有向图无环,但这m个关系式(弧)还不足以唯一确定这n个顶点之间的优先关系。
//————————————————
//版权声明:本文为CSDN博主「珞喻小森林」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
//原文链接:https://blog.csdn.net/m0_37357063/article/details/103224795



#include<stdio.h>
#include<stdlib.h>

typedef struct ArcNode {
	int index;
	struct ArcNode* next;
}ArcNode;

int main()
{
	int n, m;
	scanf("%d %d", &n, &m);
	int i;
	char u,op,v;
	ArcNode *temp = NULL;

	//相较于malloc函数,calloc函数会自动将内存初始化为0;
	ArcNode **headPtr = (ArcNode**)calloc(n + 1, sizeof(ArcNode*));
	if (headPtr == NULL)
	{
		printf("calloc headPtr fail!\n");
			return 1;
	}
	ArcNode **tailPtr = (ArcNode**)calloc(n + 1, sizeof(ArcNode*));
	if (tailPtr == NULL)
	{
		printf("calloc tailPtr fail!\n");
			return 1;
	}

	for (i = 1; i < n+1; i++)
	{
		temp = (ArcNode*)malloc(sizeof(ArcNode));
		temp->index = -1;
		temp->next = NULL;
		headPtr[i] = temp;
		tailPtr[i] = temp;
	}

	int *indegree = (int*)calloc(n + 1, sizeof(int));

	int *zeroIndegreeStack = (int*)calloc(n, sizeof(int));
	int zerotop = 0;

	int *topoStack = (int*)calloc(n, sizeof(int));
	int topotop = 0;

	for (i = 0; i<m; i++)
	{
		scanf("%c%c%c", &u, &op, &v);
		int idx_u = u - 'A' + 1;
		int idx_v = v - 'A' + 1;
		indegree[idx_v]++;

		temp = (ArcNode*)malloc(sizeof(ArcNode));
		temp->index = idx_v;
		temp->next = NULL;

		tailPtr[idx_u]->next = temp;
		tailPtr[idx_u] = temp;
	}

	for (i = 1; i< n + 1; i++)
	{
		if (indegree[i] == 0)
		{
			zeroIndegreeStack[zerotop] = i;
			zerotop++;
		}
	}
	int zeroCount = 0;
	for (i = 1; i< n + 1; i++)
	{
		if (indegree[i] == 0)
		{
			zeroCount++;
		}
	}
	if (zeroCount > 1)
	{
		printf("Sorted sequence cannot be determined.\n");
	}

	int count = 0;
	while (0 != zerotop)
	{
		zerotop--;
		int index = zeroIndegreeStack[zerotop];
		
		topoStack[topotop] = index;
		topotop++;
		count++;

		for (temp = headPtr[index]->next; temp != NULL; temp = temp->next)
		{
			int k = temp->index;
			if ((--indegree[k]) == 0)
			{
				zeroIndegreeStack[zerotop] = k;
				zerotop++;
			}
		}

		indegree[index] = -1;

		int zeroCount = 0;
		for (i = 1; i< n + 1; i++)
		{
			if (indegree[i] == 0)
			{
				zeroCount++;
			}
		}
		if (zeroCount > 1)
		{
			printf("Sorted sequence cannot be determined.\n");
		}
	}
	if (count < n)
	{
		printf("Inconsistency found after i relations.\n");
	}
	else
	{
		printf("Sorted sequence determined after i relations:");
		for (i = 0; i<topotop; i++)
		{
			printf("%c", topoStack[i] - 1 + 'A');
		}
		printf(".\n");
	}


	//for (int i = 0; i< n + 1; i++)
	//{
	//	free(headPtr[i]);
	//	headPtr[i] = NULL;
	//	free(tailPtr[i]);
	//	headPtr[i] = NULL;
	//}

	//free(indegree);
	//indegree = NULL;
	//free(zeroIndegreeStack);
	//zeroIndegreeStack = NULL;
	//free(topoStack);
	//topoStack = NULL;


	system("pause");
	return 0;
}






 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值