首页 > 其他分享 >AtCoder Beginner Contest 315 - E (toposort)

AtCoder Beginner Contest 315 - E (toposort)

时间:2023-08-20 23:14:36浏览次数:36  
标签:toposort AtCoder int 拓扑 long while 315 push define

目录

E - Prerequisites

题意
n 本书,序号 1 ~ n。给定阅读每本书之前必须要看的书的序号。
请你输出任意一种看第一本书所需看书数量最少的方法

思路
利用拓扑序列
先对书之间的制约关系建图,再利用 bfs 找到包含书本 1 的连通块,再对全图进行拓扑排序得到拓扑序列,最后利用这个序列给出包含书本 1 的连通块的书的看书顺序,最后输出即可

本题就是靠你拓扑排序的利用。那么对于任意一本书的看书顺序均可求解。

写的时候遇到一个小问题:sort 函数比较函数利用 lambda 表达式,lambda 表达式值捕获超时,引用捕获嘎嘎快

代码

//>>>Qiansui
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define mem(x,y) memset(x, y, sizeof(x))
#define debug(x) cout << #x << " = " << x << '\n'
#define debug2(x,y) cout << #x << " = " << x << " " << #y << " = "<< y << '\n'
//#define int long long

using namespace std;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pull;
typedef pair<double, double> pdd;
/*

*/
const int maxm = 2e5 + 5, inf = 0x3f3f3f3f, mod = 998244353;

void solve(){
	int n;
	cin >> n;
	int c, p;
	vector<int> e[n + 1], in(n + 1, 0);
	for(int i = 1; i <= n; ++ i){
		cin >> c;
		while(c --){
			cin >> p;
			e[i].push_back(p);
			++ in[p];
		}
	}
	//bfs
	vector<bool> f(n + 1, false);
	queue<int> q;
	q.push(1);
	while(!q.empty()){
		int u = q.front(); q.pop();
		for(auto v : e[u]){
			if(!f[v]){
				f[v] = true;
				q.push(v);
			}
		}
	}
	//topo
	for(int i = 1; i <= n; ++ i){
		if(in[i] == 0) q.push(i);
	}
	vector<int> order(n + 1), t;
	while(!q.empty()){
		int u = q.front(); q.pop();
		t.push_back(u);
		for(auto v : e[u]){
			-- in[v];
			if(in[v] == 0) q.push(v);
		}
	}
	//ans
	for(int i = 0; i < n; ++ i){
		order[t[i]] = i;
	}
	vector<int> ans;
	for(int i = 2; i <= n; ++ i)
		if(f[i]) ans.push_back(i);
	sort(ans.begin(), ans.end(), [&](int x, int y){
		return order[x] > order[y];
	});
	int len = ans.size();
	for(int i = 0; i < len; ++ i){
		cout << ans[i] << " \n"[i == len - 1];
	}
	return ;
}

signed main(){
	ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
	int _ = 1;
	// cin >> _;
	while(_ --){
		solve();
	}
	return 0;
}

标签:toposort,AtCoder,int,拓扑,long,while,315,push,define
From: https://www.cnblogs.com/Qiansui/p/17644815.html

相关文章

  • Atcoder Beginner Contest 315 D~G
    D题意:给定一个\(n\timesm\)的字符矩形,重复执行以下操作直到删除字符数为0:对于每一行,若有且仅有一种字符存在,且个数大于1,将这些字符标记对于每一列,若有且仅有一种字符存在,且个数大于1,将这些字符标记删除所有标记的字符求最后还能剩下多少字符。注意到每一行每一列最多被......
  • AtCoder 题目集2
    AtCoder题目集2终于迈入了一个新的阶段,接下来希望质量能高一点吧。现在我主要刷的是1600左右的题,毕竟实力太拉,只能按照”分上200“的策略。(我觉得类型标个“思维”貌似没啥意义,毕竟AT几乎全是思维啊...)编号(NO.)题目难度类型1ABC201E1694,medium思维,XOR......
  • Atcoder Beginner Contest 315 解题报告
    AtcoderBeginnerContest315ContestlinkHintsD尝试优化暴力。A-tcdr没啥好说的,模拟。代码实现voidSolve(){ while(charch=getchar()) { if(!isalpha(ch))return; if(ch!='a'&&ch!='e'&&ch!='i'&&ch!='o......
  • AtCoder Beginner Contest 315
    A模拟,代码。B模拟,代码。C我们发现美味度最高的食物必选,排序后枚举即可。代码。D模拟。代码。EDFS。代码。F我们发现\(2^C\)增长很快,因此不选的数量最多只有\(\log\)次,直接DP即可。代码。G我们枚举\(i\),那么也就是求出\(Bj+Ck=X-Ai(1\lej\leN,1\lek\l......
  • AtCoder 题目集1
    AtCoder题目集1这是一个AT个人刷题总结的开始,感觉确实应该做一做这种总结,如果只是不断的刷题,感觉貌似也没有什么意思,还不如时常适当的回望一下过去的好题。希望能一直做下去吧。update(22.12.14):AT赛后总结归为另外一栏,此处为过去AT题目的记录。总结了一些比较有趣或者有思......
  • ABC315
    T1:tcdr模拟代码实现#include<bits/stdc++.h>usingnamespacestd;intmain(){strings;cin>>s;erase_if(s,[](charc){returnranges::count("aeiou",c);});cout<<s<<'\n';......
  • IT3158 业务决策建模
    IT3158BusinessDecisionModellingAssignment1:LinearProgramming,SensitivityAnalysis,andIntegerLinearProgramming-usingMicrosoftExcelSolverThisassignmentisworth30%ofyourfinalmark(subjecttothehurdlesdescribedintheFIT3158UnitGu......
  • AtCoder Beginner Contest 288 - C Don't be cycle 删除图中最少的边使得图中无环
    C-Don'tbecycle题意给定一个n个顶点,m条边的无向图,你需要删除图中的一些边使得图中不存在环问你需要删除的最少边数?思路考虑连通块的生成树一个由n个顶点组成的连通块最多只能有n-1条边,不然就会成环。那么对于本题,我们只需要找到每个连通块的顶点数,那么每个连......
  • Atcoder_[abc284E]Count Simple Paths题解
    题目链接这题就是很简单的图上深搜,我觉得放在E题太水了,代码里有详细注释。#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongvector<int>v[200010];//邻接表intans;//答案boolvis[200010];//vis[i]记录i号点有没有被访问过voiddfs(intx)......
  • AtCoder Beginner Contest 311 - D(思维题)
    目录D-GridIceFloorABC简单题D思维题D-GridIceFloor题意给定一个\(n\timesm\)的矩阵,矩阵每个位置上的字符要么是'.'要么是'#',保证矩阵的最外围一圈都是'#'。玩家初始位于位置(2,2)。玩家可以进行移动,但是移动有条件:玩家首先选定一个移动方向,之后在这个方......