欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

拓扑排序题目

程序员文章站 2022-04-06 15:33:36
...

 

 

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;
}






 

 

 

相关标签: 编程练习