拓撲排序題目

 

 

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






 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章