PTA 7-55 剿灭魔教 (30分)(拓扑排序bfs版)

剿灭了魔教的分舵,五行侠杨凡提出一个建议:在魔教的分舵里设下机关,然后诱魔教的部队进入机关阵,再发动机关阵,一举消灭魔教部队。这个计划得到了一行人的一致赞同。杨帆拿出了安装机关所需要的总计N个部件,告诉了大家安装的两个注意事项: 1、某些部件安装时需要另一些部件已安装。例如要安装滑轮,必须先安装好支架。 2、当一些部件都可以安装时,应当先安装编号较小的部件。 因为要安装的部件非常多,所以他们想请你写个程序来帮忙计算出机关安装的正确顺序,你能做到么?

输入格式:

输入的第一行是一个数T,表示了要安装的不同机关的数目。接下来包含T个机关的信息,每组的第一行是两个数N和M(1<=N<=100000,0<=M<=100000),接下来M行两个数Ai和Bi(1<=Ai,Bi<=N),表示要安装第Ai个部件,就必须先安装第Bi个部件。

输出格式:

包含T行,每行是一个排列,表示一个安装的顺序,每个部件序号之间空格符隔开。如果无解,就输出一个-1。

输入样例:

在这里给出一组输入。例如:

3
7 10
2 1
3 1
4 1
5 2
6 2
5 3
6 3
6 4
7 5
7 6
5 0
3 3
1 2
2 3
3 1

输出样例:

1 2 3 4 5 6 7 
1 2 3 4 5 
-1 

注:每个数字后均有空格。

解题

要求尽量吧编号小的排在前面,则用到最小优先队列
参考:https://blog.csdn.net/qq_45349225/article/details/104790629
代码:

#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
const int maxn = 1e5 + 2;
int Indegree[maxn];

typedef struct ENode{
	int v1, v2;
} * Edge;

struct AdjVNode{
	int AdjV;
	AdjVNode *Next;
};
typedef struct VNode{
	AdjVNode *FirstEdge;
} AdjVList[maxn];
typedef struct GNode{
	int Nv, Ne;
	AdjVList L;
} * Graph;

void InsertEdge(Graph G, Edge E)
{
	AdjVNode *A = new AdjVNode;
	A->AdjV = E->v2;
	A->Next = G->L[E->v1].FirstEdge;
	G->L[E->v1].FirstEdge = A;
}

void DestroyGraph(Graph G)
{
	AdjVNode *A;
	for (int i = 1; i <= G->Nv; i++)
		while (G->L[i].FirstEdge)
		{
			A = G->L[i].FirstEdge;
			G->L[i].FirstEdge = A->Next;
			delete A;
		}
	delete G;
}

bool TopSort(Graph G, int TopOrder[])
{
	priority_queue<int, vector<int>, greater<int> > q;		//最小优先队列
	for (int i = 1; i <= G->Nv; i++)
		if(!Indegree[i])
			q.push(i);

	int cnt = 0;
	AdjVNode *A;
	while (!q.empty())
	{
		int v = q.top();
		TopOrder[cnt++] = v, q.pop();
		A = G->L[v].FirstEdge;
		while (A)
		{
			if(--Indegree[A->AdjV] == 0)
				q.push(A->AdjV);
			A = A->Next;
		}
	}
	if(cnt == G->Nv)
		return true;
	else
		return false;
}

int main()
{
	int T, N, M;
	int TopOrder[maxn];
	cin >> T;
	while (T--)
	{
		cin >> N >> M;
		Graph G = new GNode();
		G->Nv = N, G->Ne = M;

		memset(TopOrder, 0, sizeof(TopOrder));
		memset(Indegree, 0, sizeof(Indegree));

		Edge E = new ENode;
		for (int i = 0; i < M; i++)
		{
			cin >> E->v2 >> E->v1;
			InsertEdge(G, E);
			Indegree[E->v2]++;
		}
		delete E;

		if(!TopSort(G, TopOrder))
			cout << "-1 " << endl;
		else{
			for (int i = 0; i < G->Nv; i++)
				cout << TopOrder[i] << " ";
			cout << endl;
		}

		DestroyGraph(G);
	}

	system("pause");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: pta7-5是一个任务,要求对一系列英文单词进行排序。在进行单词排序时,我们可以按照字母顺序进行排序,这样可以更直观地呈现出单词的顺序。首先,我们需要将所有的英文单词按照字母顺序进行排列,可以使用字母表作为排序的参考。其次,对于开头相同的单词,我们可以再根据第二个字母的顺序进行排序。依此类推,对于更多字母相同的单词,我们可以按照第三个、第四个字母以此类推进行排序。最后,将排序后的单词逐一列出,即可完成pta7-5任务。在实际操作时,我们可以使用计算机编程语言中的排序算法来完成这个任务,如使用Python语言中的sorted()函数。通过这个函数,我们可以很方便地对一批英文单词进行排序,并输出排序后的结果。完成排序后,你将得到一系列按照字母顺序排列的英文单词列表,如["apple","banana","cat","dog","elephant"]。这样的排序结果对于后续的数据析和处理工作非常有用,也能更好地展示出单词之间的关系和规律。总之,pta7-5的任务要求我们对英文单词进行排序,通过使用排序算法和计算机编程语言,我们可以高效地完成这个任务。 ### 回答2: pta7-5是一个英文单词排序题目。要求将一串英文单词按字母顺序进行排序。 首先,我们需要将这些单词拆成一个个独立的单词。然后,我们可以使用任何一种有效的排序算法来对这些单词按字母顺序进行排序。 一种常用的排序算法是冒泡排序。冒泡排序的基本思想是依次比较相邻的两个元素,如果它们的顺序不对就交换它们的位置,直到整个序列都有序为止。 假设给定的一串英文单词为:apple, banana, orange, cat, dog 按照冒泡排序的步骤,首先比较相邻的两个单词,如果顺序不对就交换它们的位置: apple, banana, orange, cat, dog (原始顺序) banana, apple, orange, cat, dog (比较apple和banana,发现顺序不对,交换位置) banana, apple, orange, cat, dog (比较banana和orange,顺序正确,不交换位置) banana, apple, orange, cat, dog (比较orange和cat,顺序正确,不交换位置) banana, apple, cat, orange, dog (比较cat和dog,发现顺序不对,交换位置) 第一次排序完成后,最大的单词dog会出现在最后的位置。 按照同样的步骤,再次进行排序: banana, apple, cat, orange, dog (比较banana和apple,顺序正确,不交换位置) banana, apple, cat, orange, dog (比较apple和cat,顺序正确,不交换位置) banana, apple, cat, orange, dog (比较cat和orange,顺序正确,不交换位置) banana, apple, cat, dog, orange (比较orange和dog,发现顺序不对,交换位置) 再次排序完成后,第二大的单词orange会出现在倒数第二的位置。 按照同样的步骤,继续进行排序: banana, apple, cat, dog, orange (比较banana和apple,顺序正确,不交换位置) banana, apple, cat, dog, orange (比较apple和cat,顺序正确,不交换位置) banana, apple, cat, dog, orange (比较cat和dog,顺序正确,不交换位置) banana, apple, cat, dog, orange (比较dog和orange,顺序正确,不交换位置) 最后一次排序完成后,剩下的单词已经按照字母顺序进行排序。 最终的排序结果为:apple, banana, cat, dog, orange。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值