您当前的位置: 首页 >  蓝桥杯

不牌不改

暂无认证

  • 0浏览

    0关注

    422博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

蓝桥杯算法提高VIP-卡勒沃夫之弱水路三千(提高型)

不牌不改 发布时间:2021-08-08 10:09:43 ,浏览量:0

题目

题目链接

题解

拓扑排序(应该也有其他方法,但对于这类题拓扑是通解)。 本题解对会拓扑和STL的同学比较友好,不会的同学可以去别的博客学习一下,毕竟总会用到的。

在蓝桥杯里,也做过好几个拓扑的题了。 如果你会拓扑,那么这个题难在如何对使用合适的STL保存数据和处理数据。

详细介绍一下代码中变量的含义后,配合代码注释食用最佳。 就是一道拓扑模板题,但是所用数据结构比较麻烦难以理解。

map idid[str] = c 表示字符串str的编号为c,在本题中一个名字对应一个编号,此数据结构用于记录每一个名字的编号是多少。之所以采用编号的思想是因为后面在进行构造拓扑的无向图时会比较方便,而用字符串难以实现; ids:每遇到一个没有出现过的字符串,就要为这个字符串设置编号ids,出现一个新字符串ids++。用于给字符串编号; string s1, s2:输入的字符串; string ans[N]:输出拓扑序列就是通过这个函数输出的,即保存答案,ans[i]排序为i的字符串是什么; string nameofid[N]:编号对应的名字是什么,nameofid[i]表示编号为i的名字是什么; vector name:全部名字都保存在这里,不重复存; int ne[M], e[M], h[N], idx:这几个应该比较熟悉,就是邻接表的几个变量。ne[i]e[i]都表示边的编号为i对应的点编号,h[i]表示名字对应编号为i对应的边编号; T, n:如题; in[N]in[i]表示名字编号为i对应的入度,拓扑排序中用到; cnt:控制ans数组的个数。这个题目的意思就是必然存在拓扑序列,因此最终ans的元素数量其实就是出现的字符串的数量,即ids = cnt

代码
// https://www.dotcpp.com/oj/problem1506.html
#include
using namespace std;
const int N = 110; // 题目说最多13个人,不知道为什么只有开到100+才能不出“运行错误” 
const int M = 110;


map id;
int ne[M], e[M], h[N], T, n, in[N], cnt, ids, idx;
string s1, s2, ans[N], nameofid[N];
vector name;

void add(int a, int b) { // 传入的参数为名字对应的编号 
	e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

void topsort() {
	
	int m = name.size();
	queue q; // 元素为名字 
	
	for(int i = 0;i >T;
	while(T--) {
		cin>>n;
		
		// 初始化 
		id.clear();name.clear();
		memset(in, 0, sizeof in);
		memset(h, -1, sizeof h);
		cnt = 0, idx = 0, ids = 0;
		
		while(n--) {
			cin>>s1>>s2;
			if(!id[s1]) id[s1] = ++ ids, nameofid[ids] = s1, name.push_back(s1); // 新出现的就ids++ 
			if(!id[s2]) id[s2] = ++ ids, nameofid[ids] = s2, name.push_back(s2);
			add(id[s1], id[s2]);
			in[id[s2]] ++;
		}	
		
		topsort();
		
		for(int i = 1;i             
关注
打赏
1662186765
查看更多评论
2.3980s