您好,欢迎来到外链网!
当前位置:外链网 » 站长资讯 » 专业问答 » 文章详细 订阅RssFeed

AtCoder Beginner Contest 226 C dfs序 逆拓扑序

来源:互联网 浏览:143次 时间:2023-04-08
题目

一个武术辛勤的小猫咪,可以学T种武术,但他只想学第T个武术,学每个武术有需要花费的时间和前置武术条件(即要先学会前置的武术)。
求他学会第T个武术需要的最少时间。

题解思路

一开始想并查集什么的,没想太明白。
如果从图论想的话,这题就可以解决了。
如果正向建图的话,不容易得出答案的。因为起点难确定。
而如果反向建图的话,从T点出发往回跑,跑到每个武术的最基础武术点(即无需前置武术的那种)。并且每个点只跑一次。记录出来的就是答案。

帖大佬的一句话

我们反向跑的时候vps云服务器当这个点以及被学过了,那就没必要再跑一遍了。

参考题解

AC代码 #include <bits/stdc++.h>//#include <unordered_map>//priority_queue#define PII pair<int,int>#define ll long longusing namespace std;const int INF = 0x3f3f3f3f;const int N = 200100 ; vector <int> head[N] ; int a[N] ; int vis[N] ; void dfs(int p ){ if ( p == 0 ) return ; for (int i = 0 ; i < head[p].size() ; i++ ) { int st = head[p][i] ; if (!vis[st]) { vis[st] = 1 ; dfs(st) ; } }}int main(){ ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); int T ; cin >> T ; for (int j = 1 ; j <= T ; j++ ) { int s , n ; cin >> s >> n ; a[j] = s ; for (int i = 1 ; i <= n ; i++ ) { int t1 ; cin >> t1 ; head[j].push_back(t1) ; } } dfs(T) ; long long ans = a[T] ; for (int i = 1 ; i < T ; i++ ) if (vis[i]) ans += a[i] ; cout << ans << "\n" ; return 0 ;}